diff --git a/initia_stdlib/doc/account.md b/initia_stdlib/doc/account.md index 5f23719..43802ef 100644 --- a/initia_stdlib/doc/account.md +++ b/initia_stdlib/doc/account.md @@ -5,20 +5,29 @@ +- [Struct `AccountInfo`](#0x1_account_AccountInfo) - [Constants](#@Constants_0) - [Function `create_account_script`](#0x1_account_create_account_script) - [Function `create_account`](#0x1_account_create_account) - [Function `create_table_account`](#0x1_account_create_table_account) - [Function `create_object_account`](#0x1_account_create_object_account) - [Function `exists_at`](#0x1_account_exists_at) +- [Function `is_blocked`](#0x1_account_is_blocked) - [Function `get_account_number`](#0x1_account_get_account_number) - [Function `get_sequence_number`](#0x1_account_get_sequence_number) - [Function `is_base_account`](#0x1_account_is_base_account) - [Function `is_object_account`](#0x1_account_is_object_account) - [Function `is_table_account`](#0x1_account_is_table_account) - [Function `is_module_account`](#0x1_account_is_module_account) -- [Function `request_create_account`](#0x1_account_request_create_account) - [Function `get_account_info`](#0x1_account_get_account_info) +- [Function `is_module_account_with_info`](#0x1_account_is_module_account_with_info) +- [Function `is_base_account_with_info`](#0x1_account_is_base_account_with_info) +- [Function `is_object_account_with_info`](#0x1_account_is_object_account_with_info) +- [Function `is_table_account_with_info`](#0x1_account_is_table_account_with_info) +- [Function `is_blocked_with_info`](#0x1_account_is_blocked_with_info) +- [Function `get_account_number_with_info`](#0x1_account_get_account_number_with_info) +- [Function `get_sequence_number_with_info`](#0x1_account_get_sequence_number_with_info) +- [Function `account_info`](#0x1_account_account_info) - [Function `create_address`](#0x1_account_create_address) - [Function `create_signer`](#0x1_account_create_signer) @@ -28,6 +37,48 @@ + + +## Struct `AccountInfo` + + + +
struct AccountInfo has copy, drop
+
+
+
+
+##### Fields
+
+
+account_number: u64
+sequence_number: u64
+account_type: u8
+is_blocked: bool
+public entry fun create_account_script(addr: address) {
@@ -111,8 +161,6 @@ This error type is used in native function.
-
public fun create_account(addr: address): u64 {
- let (found, _, _, _) = get_account_info(addr);
- assert!(!found, error::already_exists(EACCOUNT_ALREADY_EXISTS));
+ let (found, _, _, _, _) = account_info(addr);
+ assert!(
+ !found,
+ error::already_exists(EACCOUNT_ALREADY_EXISTS)
+ );
- request_create_account(addr, ACCOUNT_TYPE_BASE)
+ request_create_account(addr, 0, ACCOUNT_TYPE_BASE)
}
-public(friend) fun create_table_account(addr: address): u64 {
- let (found, _, _, _) = get_account_info(addr);
- assert!(!found, error::already_exists(EACCOUNT_ALREADY_EXISTS));
-
- request_create_account(addr, ACCOUNT_TYPE_TABLE)
+ let (found, account_number, sequence, account_type, _) = account_info(addr);
+ assert!(
+ !found || (account_type == ACCOUNT_TYPE_BASE && sequence == 0),
+ error::already_exists(EACCOUNT_ALREADY_EXISTS)
+ );
+
+ request_create_account(
+ addr,
+ account_number,
+ ACCOUNT_TYPE_TABLE
+ )
}
-public(friend) fun create_object_account(addr: address): u64 {
- let (found, account_number, _, account_type) = get_account_info(addr);
- if (found) {
+ let (found, account_number, sequence, account_type, _) = account_info(addr);
+
+ // base account with sequence 0 is considered as not created.
+ if (!found || (account_type == ACCOUNT_TYPE_BASE && sequence == 0)) {
+ request_create_account(
+ addr,
+ account_number,
+ ACCOUNT_TYPE_OBJECT
+ )
+ } else {
// When an Object is deleted, the ObjectAccount in CosmosSDK is designed
// not to be deleted in order to prevent unexpected issues. Therefore,
// in this case, the creation of an account is omitted.
@@ -199,16 +258,12 @@ as both cannot have a pubkey, there is no way to use the account externally.
} else {
abort(error::already_exists(EACCOUNT_ALREADY_EXISTS))
}
- } else {
- request_create_account(addr, ACCOUNT_TYPE_OBJECT)
}
}
-public fun exists_at(addr: address): bool {
- let (found, _, _, _) = get_account_info(addr);
+ let (found, _, _, _, _) = account_info(addr);
found
}
-#[view]
+public fun is_blocked(addr: address): bool
+
+
+
+
+##### Implementation
+
+
+public fun is_blocked(addr: address): bool {
+ let (_, _, _, _, blocked) = account_info(addr);
+ blocked
+}
+
+
+
@@ -247,12 +322,11 @@ as both cannot have a pubkey, there is no way to use the account externally.
-public fun get_account_number(addr: address): u64 {
- let (found, account_number, _, _) = get_account_info(addr);
+ let (found, account_number, _, _, _) = account_info(addr);
assert!(found, error::not_found(EACCOUNT_NOT_FOUND));
account_number
@@ -261,8 +335,6 @@ as both cannot have a pubkey, there is no way to use the account externally.
-
public fun get_sequence_number(addr: address): u64 {
- let (found, _, sequence_number, _) = get_account_info(addr);
+ let (found, _, sequence_number, _, _) = account_info(addr);
assert!(found, error::not_found(EACCOUNT_NOT_FOUND));
sequence_number
@@ -289,8 +360,6 @@ as both cannot have a pubkey, there is no way to use the account externally.
-
public fun is_base_account(addr: address): bool {
- let (found, _, _, account_type) = get_account_info(addr);
+ let (found, _, _, account_type, _) = account_info(addr);
assert!(found, error::not_found(EACCOUNT_NOT_FOUND));
account_type == ACCOUNT_TYPE_BASE
@@ -317,8 +385,6 @@ as both cannot have a pubkey, there is no way to use the account externally.
-
public fun is_object_account(addr: address): bool {
- let (found, _, _, account_type) = get_account_info(addr);
+ let (found, _, _, account_type, _) = account_info(addr);
assert!(found, error::not_found(EACCOUNT_NOT_FOUND));
account_type == ACCOUNT_TYPE_OBJECT
@@ -345,8 +410,6 @@ as both cannot have a pubkey, there is no way to use the account externally.
-
public fun is_table_account(addr: address): bool {
- let (found, _, _, account_type) = get_account_info(addr);
+ let (found, _, _, account_type, _) = account_info(addr);
assert!(found, error::not_found(EACCOUNT_NOT_FOUND));
account_type == ACCOUNT_TYPE_TABLE
@@ -373,8 +435,6 @@ as both cannot have a pubkey, there is no way to use the account externally.
-
public fun is_module_account(addr: address): bool {
- let (found, _, _, account_type) = get_account_info(addr);
+ let (found, _, _, account_type, _) = account_info(addr);
assert!(found, error::not_found(EACCOUNT_NOT_FOUND));
account_type == ACCOUNT_TYPE_MODULE
@@ -401,51 +460,203 @@ as both cannot have a pubkey, there is no way to use the account externally.
-
#[view]
+public fun get_account_info(addr: address): (bool, account::AccountInfo)
+
+
-
-## Function `request_create_account`
+##### Implementation
+public fun get_account_info(addr: address): (bool, AccountInfo) {
+ let (found, account_number, sequence_number, account_type, is_blocked) =
+ account_info(addr);
-fun request_create_account(addr: address, account_type: u8): u64
+ (found, AccountInfo { account_number, sequence_number, account_type, is_blocked })
+}
-
-Implementation
+
+
+## Function `is_module_account_with_info`
-native fun request_create_account(addr: address, account_type: u8): u64;
+
+public fun is_module_account_with_info(info: &account::AccountInfo): bool
-
+##### Implementation
-
-## Function `get_account_info`
+public fun is_module_account_with_info(info: &AccountInfo): bool {
+ info.account_type == ACCOUNT_TYPE_MODULE
+}
+
+
+
+
+
+
+## Function `is_base_account_with_info`
+
+
+
+public fun is_base_account_with_info(info: &account::AccountInfo): bool
+
+
+
+
+##### Implementation
+
+
+public fun is_base_account_with_info(info: &AccountInfo): bool {
+ info.account_type == ACCOUNT_TYPE_BASE
+}
+
+
+
+
+
+
+## Function `is_object_account_with_info`
-public fun get_account_info(addr: address): (bool, u64, u64, u8)
+public fun is_object_account_with_info(info: &account::AccountInfo): bool
-
-Implementation
+##### Implementation
-native public fun get_account_info(addr: address): (bool /* found */, u64 /* account_number */, u64 /* sequence_number */, u8 /* account_type */);
+public fun is_object_account_with_info(info: &AccountInfo): bool {
+ info.account_type == ACCOUNT_TYPE_OBJECT
+}
+
+
+
+
+
+
+## Function `is_table_account_with_info`
+
+
+
+public fun is_table_account_with_info(info: &account::AccountInfo): bool
+
+
+
+
+##### Implementation
+
+
+public fun is_table_account_with_info(info: &AccountInfo): bool {
+ info.account_type == ACCOUNT_TYPE_TABLE
+}
+
+
+
+
+
+
+## Function `is_blocked_with_info`
+
+
+
+public fun is_blocked_with_info(info: &account::AccountInfo): bool
+
+
+
+
+##### Implementation
+
+
+public fun is_blocked_with_info(info: &AccountInfo): bool {
+ info.is_blocked
+}
+
+
+
+
+
+
+## Function `get_account_number_with_info`
+
+
+
+public fun get_account_number_with_info(info: &account::AccountInfo): u64
-
+##### Implementation
+
+
+public fun get_account_number_with_info(info: &AccountInfo): u64 {
+ info.account_number
+}
+
+
+
+
+
+
+## Function `get_sequence_number_with_info`
+
+
+
+public fun get_sequence_number_with_info(info: &account::AccountInfo): u64
+
+
+
+
+##### Implementation
+
+
+public fun get_sequence_number_with_info(info: &AccountInfo): u64 {
+ info.sequence_number
+}
+
+
+
+
+
+
+## Function `account_info`
+
+
+
+public fun account_info(addr: address): (bool, u64, u64, u8, bool)
+
+
+
+
+##### Implementation
+
+
+native public fun account_info(addr: address):
+ (
+ bool /* found */,
+ u64 /* account_number */,
+ u64 /* sequence_number */,
+ u8 /* account_type */,
+ bool /* is_blocked */
+);
+
+
+
@@ -458,8 +669,7 @@ as both cannot have a pubkey, there is no way to use the account externally.
-
-Implementation
+##### Implementation
native public(friend) fun create_address(bytes: vector<u8>): address;
@@ -467,8 +677,6 @@ as both cannot have a pubkey, there is no way to use the account externally.
-
-
## Function `create_signer`
@@ -480,13 +688,8 @@ as both cannot have a pubkey, there is no way to use the account externally.
-
-Implementation
+##### Implementation
native public(friend) fun create_signer(addr: address): signer;
-
-
-
-
diff --git a/initia_stdlib/doc/address.md b/initia_stdlib/doc/address.md
index da7f19c..36be855 100644
--- a/initia_stdlib/doc/address.md
+++ b/initia_stdlib/doc/address.md
@@ -5,94 +5,180 @@
+- [Struct `FromSdkRequest`](#0x1_address_FromSdkRequest)
+- [Struct `FromSdkResponse`](#0x1_address_FromSdkResponse)
+- [Struct `ToSdkRequest`](#0x1_address_ToSdkRequest)
+- [Struct `ToSdkResponse`](#0x1_address_ToSdkResponse)
- [Function `from_sdk`](#0x1_address_from_sdk)
- [Function `to_sdk`](#0x1_address_to_sdk)
- [Function `to_string`](#0x1_address_to_string)
- [Function `from_string`](#0x1_address_from_string)
+- [Function `to_bytes`](#0x1_address_to_bytes)
+- [Function `from_bytes`](#0x1_address_from_bytes)
-use 0x1::json;
-use 0x1::option;
+use 0x1::bcs;
+use 0x1::from_bcs;
+use 0x1::json;
use 0x1::query;
-use 0x1::simple_json;
use 0x1::string;
-
+
-## Function `from_sdk`
+## Struct `FromSdkRequest`
-public fun from_sdk(sdk_addr: string::String): address
+struct FromSdkRequest has copy, drop
-
-Implementation
+##### Fields
-public fun from_sdk(sdk_addr: String): address {
- let obj = simple_json::empty();
- simple_json::set_object(&mut obj, option::none<String>());
- simple_json::increase_depth(&mut obj);
+
+-
+
sdk_addr: string::String
+
+-
- simple_json::set_string(&mut obj, option::some(string::utf8(b"sdk_addr")), sdk_addr);
+
+
- let req = json::stringify(simple_json::to_json_object(&obj));
- let res = query::query_custom(b"from_sdk_address", *string::bytes(&req));
- let res = simple_json::from_json_object(json::parse(string::utf8(res)));
- simple_json::increase_depth(&mut res);
- let (_, data) = json::unpack_elem(simple_json::borrow(&mut res));
+
- from_string(json::as_string(data))
-}
+## Struct `FromSdkResponse`
+
+
+
+struct FromSdkResponse has copy, drop
-
+##### Fields
-
-## Function `to_sdk`
+
+-
+
vm_addr: address
+
+-
+
+
-public fun to_sdk(vm_addr: address): string::String
+
+
+## Struct `ToSdkRequest`
+
+
+
+struct ToSdkRequest has copy, drop
-
-Implementation
+##### Fields
+
+
+
+-
+
vm_addr: address
+
+-
+
+
+
+
+
+
+
+## Struct `ToSdkResponse`
-public fun to_sdk(vm_addr: address): String {
- let obj = simple_json::empty();
- simple_json::set_object(&mut obj, option::none<String>());
- simple_json::increase_depth(&mut obj);
- simple_json::set_string(&mut obj, option::some(string::utf8(b"vm_addr")), to_string(vm_addr));
+struct ToSdkResponse has copy, drop
+
+
+
+
+##### Fields
+
+
+
+-
+
sdk_addr: string::String
+
+-
+
+
+
+
+
+
+
+## Function `from_sdk`
+
+
+
+public fun from_sdk(sdk_addr: string::String): address
+
- let req = json::stringify(simple_json::to_json_object(&obj));
- let res = query::query_custom(b"to_sdk_address", *string::bytes(&req));
- let res = simple_json::from_json_object(json::parse(string::utf8(res)));
- simple_json::increase_depth(&mut res);
- let (_, data) = json::unpack_elem(simple_json::borrow(&mut res));
- json::as_string(data)
+##### Implementation
+
+
+public fun from_sdk(sdk_addr: String): address {
+ let res =
+ json::unmarshal<FromSdkResponse>(
+ query::query_custom(
+ b"from_sdk_address",
+ json::marshal(&FromSdkRequest { sdk_addr: sdk_addr })
+ )
+ );
+
+ res.vm_addr
}
-
+
+
+## Function `to_sdk`
+
+
+
+public fun to_sdk(vm_addr: address): string::String
+
+
+
+
+##### Implementation
+
+
+public fun to_sdk(vm_addr: address): String {
+ let res =
+ json::unmarshal<ToSdkResponse>(
+ query::query_custom(
+ b"to_sdk_address",
+ json::marshal(&ToSdkRequest { vm_addr: vm_addr })
+ )
+ );
+
+ res.sdk_addr
+}
+
+
+
@@ -105,17 +191,14 @@
-
-Implementation
+##### Implementation
-public native fun to_string(addr: address): String;
+native public fun to_string(addr: address): String;
-
-
## Function `from_string`
@@ -127,13 +210,50 @@
-
-Implementation
+##### Implementation
+
+
+native public fun from_string(addr_str: String): address;
+
+
+
+
+
+
+## Function `to_bytes`
+
+
+
+public fun to_bytes(addr: address): vector<u8>
+
+
+
+
+##### Implementation
+
+
+public fun to_bytes(addr: address): vector<u8> {
+ bcs::to_bytes(&addr)
+}
+
+
+
+
+
+
+## Function `from_bytes`
-public native fun from_string(addr_str: String): address;
+
+public fun from_bytes(bytes: vector<u8>): address
-
+##### Implementation
+
+
+public fun from_bytes(bytes: vector<u8>): address {
+ from_bcs::to_address(bytes)
+}
+
diff --git a/initia_stdlib/doc/any.md b/initia_stdlib/doc/any.md
index 635cf3b..5c68c68 100644
--- a/initia_stdlib/doc/any.md
+++ b/initia_stdlib/doc/any.md
@@ -43,8 +43,7 @@ extension: Option
-
-Fields
+##### Fields
@@ -63,8 +62,6 @@ extension: Option
-
-
## Constants
@@ -93,8 +90,7 @@ also required from T
.
-
-Implementation
+##### Implementation
public fun pack<T: drop + store>(x: T): Any {
@@ -107,8 +103,6 @@ also required from T
.
-
-
## Function `unpack`
@@ -121,20 +115,20 @@ Unpack a value from the Any
repres
-
-Implementation
+##### Implementation
public fun unpack<T>(x: Any): T {
- assert!(type_info::type_name<T>() == x.type_name, error::invalid_argument(ETYPE_MISMATCH));
+ assert!(
+ type_info::type_name<T>() == x.type_name,
+ error::invalid_argument(ETYPE_MISMATCH)
+ );
from_bytes<T>(x.data)
}
-
-
## Function `type_name`
@@ -147,15 +141,10 @@ Returns the type name of this Any
-
-Implementation
+##### Implementation
public fun type_name(x: &Any): &String {
&x.type_name
}
-
-
-
-
diff --git a/initia_stdlib/doc/aptos_hash.md b/initia_stdlib/doc/aptos_hash.md
new file mode 100644
index 0000000..e1de452
--- /dev/null
+++ b/initia_stdlib/doc/aptos_hash.md
@@ -0,0 +1,79 @@
+
+
+
+# Module `0x1::aptos_hash`
+
+AptosHash module exists to provide compatibility with aptos.
+
+
+- [Function `sha2_256`](#0x1_aptos_hash_sha2_256)
+- [Function `sha3_256`](#0x1_aptos_hash_sha3_256)
+- [Function `keccak256`](#0x1_aptos_hash_keccak256)
+
+
+use 0x1::hash;
+use 0x1::keccak;
+
+
+
+
+
+
+## Function `sha2_256`
+
+
+
+public fun sha2_256(data: vector<u8>): vector<u8>
+
+
+
+
+##### Implementation
+
+
+public fun sha2_256(data: vector<u8>): vector<u8> {
+ s2_256(data)
+}
+
+
+
+
+
+
+## Function `sha3_256`
+
+
+
+public fun sha3_256(data: vector<u8>): vector<u8>
+
+
+
+
+##### Implementation
+
+
+public fun sha3_256(data: vector<u8>): vector<u8> {
+ s3_256(data)
+}
+
+
+
+
+
+
+## Function `keccak256`
+
+
+
+public fun keccak256(data: vector<u8>): vector<u8>
+
+
+
+
+##### Implementation
+
+
+public fun keccak256(data: vector<u8>): vector<u8> {
+ k256(data)
+}
+
diff --git a/initia_stdlib/doc/base64.md b/initia_stdlib/doc/base64.md
index bb9ad92..f81b263 100644
--- a/initia_stdlib/doc/base64.md
+++ b/initia_stdlib/doc/base64.md
@@ -27,8 +27,7 @@
-
-Implementation
+##### Implementation
public fun to_string(bytes: vector<u8>): String {
@@ -38,8 +37,6 @@
-
-
## Function `from_string`
@@ -51,8 +48,7 @@
-
-Implementation
+##### Implementation
public fun from_string(str: String): vector<u8> {
@@ -62,8 +58,6 @@
-
-
## Function `encode`
@@ -75,17 +69,14 @@
-
-Implementation
+##### Implementation
-public native fun encode(bytes: vector<u8>): vector<u8>;
+native public fun encode(bytes: vector<u8>): vector<u8>;
-
-
## Function `decode`
@@ -97,13 +88,8 @@
-
-Implementation
+##### Implementation
-public native fun decode(bytes: vector<u8>): vector<u8>;
+native public fun decode(bytes: vector<u8>): vector<u8>;
-
-
-
-
diff --git a/initia_stdlib/doc/bigdecimal.md b/initia_stdlib/doc/bigdecimal.md
new file mode 100644
index 0000000..1c35a5e
--- /dev/null
+++ b/initia_stdlib/doc/bigdecimal.md
@@ -0,0 +1,1424 @@
+
+
+
+# Module `0x1::bigdecimal`
+
+
+
+- [Struct `BigDecimal`](#0x1_bigdecimal_BigDecimal)
+- [Constants](#@Constants_0)
+- [Function `from_u64`](#0x1_bigdecimal_from_u64)
+- [Function `from_u128`](#0x1_bigdecimal_from_u128)
+- [Function `from_u256`](#0x1_bigdecimal_from_u256)
+- [Function `new`](#0x1_bigdecimal_new)
+- [Function `from_scaled`](#0x1_bigdecimal_from_scaled)
+- [Function `get_scaled`](#0x1_bigdecimal_get_scaled)
+- [Function `from_scaled_le_bytes`](#0x1_bigdecimal_from_scaled_le_bytes)
+- [Function `get_scaled_le_bytes`](#0x1_bigdecimal_get_scaled_le_bytes)
+- [Function `from_ratio`](#0x1_bigdecimal_from_ratio)
+- [Function `from_ratio_u64`](#0x1_bigdecimal_from_ratio_u64)
+- [Function `from_ratio_u128`](#0x1_bigdecimal_from_ratio_u128)
+- [Function `from_ratio_u256`](#0x1_bigdecimal_from_ratio_u256)
+- [Function `rev`](#0x1_bigdecimal_rev)
+- [Function `one`](#0x1_bigdecimal_one)
+- [Function `zero`](#0x1_bigdecimal_zero)
+- [Function `eq`](#0x1_bigdecimal_eq)
+- [Function `lt`](#0x1_bigdecimal_lt)
+- [Function `le`](#0x1_bigdecimal_le)
+- [Function `gt`](#0x1_bigdecimal_gt)
+- [Function `ge`](#0x1_bigdecimal_ge)
+- [Function `is_zero`](#0x1_bigdecimal_is_zero)
+- [Function `is_one`](#0x1_bigdecimal_is_one)
+- [Function `add`](#0x1_bigdecimal_add)
+- [Function `add_by_u64`](#0x1_bigdecimal_add_by_u64)
+- [Function `add_by_u128`](#0x1_bigdecimal_add_by_u128)
+- [Function `add_by_u256`](#0x1_bigdecimal_add_by_u256)
+- [Function `sub`](#0x1_bigdecimal_sub)
+- [Function `sub_by_u64`](#0x1_bigdecimal_sub_by_u64)
+- [Function `sub_by_u128`](#0x1_bigdecimal_sub_by_u128)
+- [Function `sub_by_u256`](#0x1_bigdecimal_sub_by_u256)
+- [Function `mul`](#0x1_bigdecimal_mul)
+- [Function `mul_truncate`](#0x1_bigdecimal_mul_truncate)
+- [Function `mul_ceil`](#0x1_bigdecimal_mul_ceil)
+- [Function `mul_by_u64`](#0x1_bigdecimal_mul_by_u64)
+- [Function `mul_by_u64_truncate`](#0x1_bigdecimal_mul_by_u64_truncate)
+- [Function `mul_by_u64_ceil`](#0x1_bigdecimal_mul_by_u64_ceil)
+- [Function `mul_by_u128`](#0x1_bigdecimal_mul_by_u128)
+- [Function `mul_by_u128_truncate`](#0x1_bigdecimal_mul_by_u128_truncate)
+- [Function `mul_by_u128_ceil`](#0x1_bigdecimal_mul_by_u128_ceil)
+- [Function `mul_by_u256`](#0x1_bigdecimal_mul_by_u256)
+- [Function `mul_by_u256_truncate`](#0x1_bigdecimal_mul_by_u256_truncate)
+- [Function `mul_by_u256_ceil`](#0x1_bigdecimal_mul_by_u256_ceil)
+- [Function `div`](#0x1_bigdecimal_div)
+- [Function `div_by_u64`](#0x1_bigdecimal_div_by_u64)
+- [Function `div_by_u128`](#0x1_bigdecimal_div_by_u128)
+- [Function `div_by_u256`](#0x1_bigdecimal_div_by_u256)
+- [Function `truncate`](#0x1_bigdecimal_truncate)
+- [Function `truncate_u64`](#0x1_bigdecimal_truncate_u64)
+- [Function `truncate_u128`](#0x1_bigdecimal_truncate_u128)
+- [Function `truncate_u256`](#0x1_bigdecimal_truncate_u256)
+- [Function `round_up`](#0x1_bigdecimal_round_up)
+- [Function `round_up_u64`](#0x1_bigdecimal_round_up_u64)
+- [Function `round_up_u128`](#0x1_bigdecimal_round_up_u128)
+- [Function `round_up_u256`](#0x1_bigdecimal_round_up_u256)
+- [Function `ceil`](#0x1_bigdecimal_ceil)
+- [Function `ceil_u64`](#0x1_bigdecimal_ceil_u64)
+- [Function `ceil_u128`](#0x1_bigdecimal_ceil_u128)
+- [Function `ceil_u256`](#0x1_bigdecimal_ceil_u256)
+
+
+use 0x1::biguint;
+use 0x1::error;
+
+
+
+
+
+
+## Struct `BigDecimal`
+
+
+
+struct BigDecimal has copy, drop, store
+
+
+
+
+##### Fields
+
+
+
+-
+
scaled: biguint::BigUint
+
+-
+
+
+
+
+
+
+
+## Constants
+
+
+
+
+
+
+const EDIVISION_BY_ZERO: u64 = 101;
+
+
+
+
+
+
+
+
+const NEGATIVE_RESULT: u64 = 100;
+
+
+
+
+
+
+
+
+const DECIMAL_FRACTIONAL: u64 = 1000000000000000000;
+
+
+
+
+
+
+
+
+const FRACTIONAL_LENGTH: u64 = 18;
+
+
+
+
+
+
+## Function `from_u64`
+
+Create a BigDecimal from a u64 value by multiplying it by the fractional part.
+
+
+public fun from_u64(value: u64): bigdecimal::BigDecimal
+
+
+
+
+##### Implementation
+
+
+public fun from_u64(value: u64): BigDecimal {
+ BigDecimal {
+ scaled: biguint::mul(biguint::from_u64(value), f())
+ }
+}
+
+
+
+
+
+
+## Function `from_u128`
+
+Create a BigDecimal from a u128 value by multiplying it by the fractional part.
+
+
+public fun from_u128(value: u128): bigdecimal::BigDecimal
+
+
+
+
+##### Implementation
+
+
+public fun from_u128(value: u128): BigDecimal {
+ BigDecimal {
+ scaled: biguint::mul(biguint::from_u128(value), f())
+ }
+}
+
+
+
+
+
+
+## Function `from_u256`
+
+Create a BigDecimal from a u256 value by multiplying it by the fractional part.
+
+
+public fun from_u256(value: u256): bigdecimal::BigDecimal
+
+
+
+
+##### Implementation
+
+
+public fun from_u256(value: u256): BigDecimal {
+ BigDecimal {
+ scaled: biguint::mul(biguint::from_u256(value), f())
+ }
+}
+
+
+
+
+
+
+## Function `new`
+
+Create a BigDecimal from a BigUint value by multiplying it by the fractional part.
+
+
+public fun new(value: biguint::BigUint): bigdecimal::BigDecimal
+
+
+
+
+##### Implementation
+
+
+public fun new(value: BigUint): BigDecimal {
+ BigDecimal {
+ scaled: biguint::mul(value, f())
+ }
+}
+
+
+
+
+
+
+## Function `from_scaled`
+
+Create a BigDecimal from a scaled BigUint value.
+
+
+public fun from_scaled(scaled: biguint::BigUint): bigdecimal::BigDecimal
+
+
+
+
+##### Implementation
+
+
+public fun from_scaled(scaled: BigUint): BigDecimal {
+ BigDecimal { scaled: scaled }
+}
+
+
+
+
+
+
+## Function `get_scaled`
+
+Get the scaled value of a BigDecimal.
+
+
+public fun get_scaled(num: bigdecimal::BigDecimal): biguint::BigUint
+
+
+
+
+##### Implementation
+
+
+public fun get_scaled(num: BigDecimal): BigUint {
+ num.scaled
+}
+
+
+
+
+
+
+## Function `from_scaled_le_bytes`
+
+Create a BigDecimal from a scaled BigUint le_bytes value.
+
+
+public fun from_scaled_le_bytes(le_bytes: vector<u8>): bigdecimal::BigDecimal
+
+
+
+
+##### Implementation
+
+
+public fun from_scaled_le_bytes(le_bytes: vector<u8>): BigDecimal {
+ BigDecimal { scaled: biguint::from_le_bytes(le_bytes) }
+}
+
+
+
+
+
+
+## Function `get_scaled_le_bytes`
+
+
+
+public fun get_scaled_le_bytes(num: bigdecimal::BigDecimal): vector<u8>
+
+
+
+
+##### Implementation
+
+
+public fun get_scaled_le_bytes(num: BigDecimal): vector<u8> {
+ biguint::to_le_bytes(num.scaled)
+}
+
+
+
+
+
+
+## Function `from_ratio`
+
+
+
+public fun from_ratio(numerator: biguint::BigUint, denominator: biguint::BigUint): bigdecimal::BigDecimal
+
+
+
+
+##### Implementation
+
+
+public fun from_ratio(numerator: BigUint, denominator: BigUint): BigDecimal {
+ assert!(
+ !biguint::is_zero(denominator), error::invalid_argument(EDIVISION_BY_ZERO)
+ );
+
+ let numerator = biguint::mul(numerator, f());
+ BigDecimal { scaled: biguint::div(numerator, denominator) }
+}
+
+
+
+
+
+
+## Function `from_ratio_u64`
+
+
+
+public fun from_ratio_u64(numerator: u64, denominator: u64): bigdecimal::BigDecimal
+
+
+
+
+##### Implementation
+
+
+public fun from_ratio_u64(numerator: u64, denominator: u64): BigDecimal {
+ assert!(denominator != 0, error::invalid_argument(EDIVISION_BY_ZERO));
+
+ let numerator = biguint::from_u128(
+ (numerator as u128) * (DECIMAL_FRACTIONAL as u128)
+ );
+ let denominator = biguint::from_u64(denominator);
+
+ BigDecimal { scaled: biguint::div(numerator, denominator) }
+}
+
+
+
+
+
+
+## Function `from_ratio_u128`
+
+
+
+public fun from_ratio_u128(numerator: u128, denominator: u128): bigdecimal::BigDecimal
+
+
+
+
+##### Implementation
+
+
+public fun from_ratio_u128(numerator: u128, denominator: u128): BigDecimal {
+ assert!(denominator != 0, error::invalid_argument(EDIVISION_BY_ZERO));
+
+ let numerator = biguint::from_u256(
+ (numerator as u256) * (DECIMAL_FRACTIONAL as u256)
+ );
+ let denominator = biguint::from_u128(denominator);
+
+ BigDecimal { scaled: biguint::div(numerator, denominator) }
+}
+
+
+
+
+
+
+## Function `from_ratio_u256`
+
+
+
+public fun from_ratio_u256(numerator: u256, denominator: u256): bigdecimal::BigDecimal
+
+
+
+
+##### Implementation
+
+
+public fun from_ratio_u256(numerator: u256, denominator: u256): BigDecimal {
+ assert!(denominator != 0, error::invalid_argument(EDIVISION_BY_ZERO));
+
+ let numerator = biguint::mul(biguint::from_u256(numerator), f());
+ let denominator = biguint::from_u256(denominator);
+
+ BigDecimal { scaled: biguint::div(numerator, denominator) }
+}
+
+
+
+
+
+
+## Function `rev`
+
+
+
+public fun rev(num: bigdecimal::BigDecimal): bigdecimal::BigDecimal
+
+
+
+
+##### Implementation
+
+
+public fun rev(num: BigDecimal): BigDecimal {
+ let fractional = f();
+ BigDecimal {
+ scaled: biguint::div(biguint::mul(fractional, fractional), num.scaled)
+ }
+}
+
+
+
+
+
+
+## Function `one`
+
+
+
+public fun one(): bigdecimal::BigDecimal
+
+
+
+
+##### Implementation
+
+
+public fun one(): BigDecimal {
+ BigDecimal { scaled: f() }
+}
+
+
+
+
+
+
+## Function `zero`
+
+
+
+public fun zero(): bigdecimal::BigDecimal
+
+
+
+
+##### Implementation
+
+
+public fun zero(): BigDecimal {
+ BigDecimal { scaled: biguint::zero() }
+}
+
+
+
+
+
+
+## Function `eq`
+
+
+
+public fun eq(num1: bigdecimal::BigDecimal, num2: bigdecimal::BigDecimal): bool
+
+
+
+
+##### Implementation
+
+
+public fun eq(num1: BigDecimal, num2: BigDecimal): bool {
+ biguint::eq(num1.scaled, num2.scaled)
+}
+
+
+
+
+
+
+## Function `lt`
+
+
+
+public fun lt(num1: bigdecimal::BigDecimal, num2: bigdecimal::BigDecimal): bool
+
+
+
+
+##### Implementation
+
+
+public fun lt(num1: BigDecimal, num2: BigDecimal): bool {
+ biguint::lt(num1.scaled, num2.scaled)
+}
+
+
+
+
+
+
+## Function `le`
+
+
+
+public fun le(num1: bigdecimal::BigDecimal, num2: bigdecimal::BigDecimal): bool
+
+
+
+
+##### Implementation
+
+
+public fun le(num1: BigDecimal, num2: BigDecimal): bool {
+ biguint::le(num1.scaled, num2.scaled)
+}
+
+
+
+
+
+
+## Function `gt`
+
+
+
+public fun gt(num1: bigdecimal::BigDecimal, num2: bigdecimal::BigDecimal): bool
+
+
+
+
+##### Implementation
+
+
+public fun gt(num1: BigDecimal, num2: BigDecimal): bool {
+ biguint::gt(num1.scaled, num2.scaled)
+}
+
+
+
+
+
+
+## Function `ge`
+
+
+
+public fun ge(num1: bigdecimal::BigDecimal, num2: bigdecimal::BigDecimal): bool
+
+
+
+
+##### Implementation
+
+
+public fun ge(num1: BigDecimal, num2: BigDecimal): bool {
+ biguint::ge(num1.scaled, num2.scaled)
+}
+
+
+
+
+
+
+## Function `is_zero`
+
+
+
+public fun is_zero(num: bigdecimal::BigDecimal): bool
+
+
+
+
+##### Implementation
+
+
+public fun is_zero(num: BigDecimal): bool {
+ biguint::is_zero(num.scaled)
+}
+
+
+
+
+
+
+## Function `is_one`
+
+
+
+public fun is_one(num: bigdecimal::BigDecimal): bool
+
+
+
+
+##### Implementation
+
+
+public fun is_one(num: BigDecimal): bool {
+ biguint::eq(num.scaled, f())
+}
+
+
+
+
+
+
+## Function `add`
+
+
+
+public fun add(num1: bigdecimal::BigDecimal, num2: bigdecimal::BigDecimal): bigdecimal::BigDecimal
+
+
+
+
+##### Implementation
+
+
+public fun add(num1: BigDecimal, num2: BigDecimal): BigDecimal {
+ BigDecimal { scaled: biguint::add(num1.scaled, num2.scaled) }
+}
+
+
+
+
+
+
+## Function `add_by_u64`
+
+
+
+public fun add_by_u64(num1: bigdecimal::BigDecimal, num2: u64): bigdecimal::BigDecimal
+
+
+
+
+##### Implementation
+
+
+public fun add_by_u64(num1: BigDecimal, num2: u64): BigDecimal {
+ BigDecimal {
+ scaled: biguint::add(num1.scaled, from_u64(num2).scaled)
+ }
+}
+
+
+
+
+
+
+## Function `add_by_u128`
+
+
+
+public fun add_by_u128(num1: bigdecimal::BigDecimal, num2: u128): bigdecimal::BigDecimal
+
+
+
+
+##### Implementation
+
+
+public fun add_by_u128(num1: BigDecimal, num2: u128): BigDecimal {
+ BigDecimal {
+ scaled: biguint::add(num1.scaled, from_u128(num2).scaled)
+ }
+}
+
+
+
+
+
+
+## Function `add_by_u256`
+
+
+
+public fun add_by_u256(num1: bigdecimal::BigDecimal, num2: u256): bigdecimal::BigDecimal
+
+
+
+
+##### Implementation
+
+
+public fun add_by_u256(num1: BigDecimal, num2: u256): BigDecimal {
+ BigDecimal {
+ scaled: biguint::add(num1.scaled, from_u256(num2).scaled)
+ }
+}
+
+
+
+
+
+
+## Function `sub`
+
+
+
+public fun sub(num1: bigdecimal::BigDecimal, num2: bigdecimal::BigDecimal): bigdecimal::BigDecimal
+
+
+
+
+##### Implementation
+
+
+public fun sub(num1: BigDecimal, num2: BigDecimal): BigDecimal {
+ assert!(ge(num1, num2), error::invalid_argument(NEGATIVE_RESULT));
+ BigDecimal { scaled: biguint::sub(num1.scaled, num2.scaled) }
+}
+
+
+
+
+
+
+## Function `sub_by_u64`
+
+
+
+public fun sub_by_u64(num1: bigdecimal::BigDecimal, num2: u64): bigdecimal::BigDecimal
+
+
+
+
+##### Implementation
+
+
+public fun sub_by_u64(num1: BigDecimal, num2: u64): BigDecimal {
+ let num2 = from_u64(num2);
+ assert!(ge(num1, num2), error::invalid_argument(NEGATIVE_RESULT));
+ BigDecimal { scaled: biguint::sub(num1.scaled, num2.scaled) }
+}
+
+
+
+
+
+
+## Function `sub_by_u128`
+
+
+
+public fun sub_by_u128(num1: bigdecimal::BigDecimal, num2: u128): bigdecimal::BigDecimal
+
+
+
+
+##### Implementation
+
+
+public fun sub_by_u128(num1: BigDecimal, num2: u128): BigDecimal {
+ let num2 = from_u128(num2);
+ assert!(ge(num1, num2), error::invalid_argument(NEGATIVE_RESULT));
+ BigDecimal { scaled: biguint::sub(num1.scaled, num2.scaled) }
+}
+
+
+
+
+
+
+## Function `sub_by_u256`
+
+
+
+public fun sub_by_u256(num1: bigdecimal::BigDecimal, num2: u256): bigdecimal::BigDecimal
+
+
+
+
+##### Implementation
+
+
+public fun sub_by_u256(num1: BigDecimal, num2: u256): BigDecimal {
+ let num2 = from_u256(num2);
+ assert!(ge(num1, num2), error::invalid_argument(NEGATIVE_RESULT));
+ BigDecimal { scaled: biguint::sub(num1.scaled, num2.scaled) }
+}
+
+
+
+
+
+
+## Function `mul`
+
+
+
+public fun mul(num1: bigdecimal::BigDecimal, num2: bigdecimal::BigDecimal): bigdecimal::BigDecimal
+
+
+
+
+##### Implementation
+
+
+public fun mul(num1: BigDecimal, num2: BigDecimal): BigDecimal {
+ BigDecimal {
+ scaled: biguint::div(biguint::mul(num1.scaled, num2.scaled), f())
+ }
+}
+
+
+
+
+
+
+## Function `mul_truncate`
+
+
+
+public fun mul_truncate(num1: bigdecimal::BigDecimal, num2: bigdecimal::BigDecimal): biguint::BigUint
+
+
+
+
+##### Implementation
+
+
+public fun mul_truncate(num1: BigDecimal, num2: BigDecimal): BigUint {
+ truncate(mul(num1, num2))
+}
+
+
+
+
+
+
+## Function `mul_ceil`
+
+
+
+public fun mul_ceil(num1: bigdecimal::BigDecimal, num2: bigdecimal::BigDecimal): biguint::BigUint
+
+
+
+
+##### Implementation
+
+
+public fun mul_ceil(num1: BigDecimal, num2: BigDecimal): BigUint {
+ ceil(mul(num1, num2))
+}
+
+
+
+
+
+
+## Function `mul_by_u64`
+
+
+
+public fun mul_by_u64(num1: bigdecimal::BigDecimal, num2: u64): bigdecimal::BigDecimal
+
+
+
+
+##### Implementation
+
+
+public fun mul_by_u64(num1: BigDecimal, num2: u64): BigDecimal {
+ BigDecimal { scaled: biguint::mul_by_u64(num1.scaled, num2) }
+}
+
+
+
+
+
+
+## Function `mul_by_u64_truncate`
+
+
+
+public fun mul_by_u64_truncate(num1: bigdecimal::BigDecimal, num2: u64): u64
+
+
+
+
+##### Implementation
+
+
+public fun mul_by_u64_truncate(num1: BigDecimal, num2: u64): u64 {
+ truncate_u64(mul_by_u64(num1, num2))
+}
+
+
+
+
+
+
+## Function `mul_by_u64_ceil`
+
+
+
+public fun mul_by_u64_ceil(num1: bigdecimal::BigDecimal, num2: u64): u64
+
+
+
+
+##### Implementation
+
+
+public fun mul_by_u64_ceil(num1: BigDecimal, num2: u64): u64 {
+ ceil_u64(mul_by_u64(num1, num2))
+}
+
+
+
+
+
+
+## Function `mul_by_u128`
+
+
+
+public fun mul_by_u128(num1: bigdecimal::BigDecimal, num2: u128): bigdecimal::BigDecimal
+
+
+
+
+##### Implementation
+
+
+public fun mul_by_u128(num1: BigDecimal, num2: u128): BigDecimal {
+ BigDecimal { scaled: biguint::mul_by_u128(num1.scaled, num2) }
+}
+
+
+
+
+
+
+## Function `mul_by_u128_truncate`
+
+
+
+public fun mul_by_u128_truncate(num1: bigdecimal::BigDecimal, num2: u128): u128
+
+
+
+
+##### Implementation
+
+
+public fun mul_by_u128_truncate(num1: BigDecimal, num2: u128): u128 {
+ truncate_u128(mul_by_u128(num1, num2))
+}
+
+
+
+
+
+
+## Function `mul_by_u128_ceil`
+
+
+
+public fun mul_by_u128_ceil(num1: bigdecimal::BigDecimal, num2: u128): u128
+
+
+
+
+##### Implementation
+
+
+public fun mul_by_u128_ceil(num1: BigDecimal, num2: u128): u128 {
+ ceil_u128(mul_by_u128(num1, num2))
+}
+
+
+
+
+
+
+## Function `mul_by_u256`
+
+
+
+public fun mul_by_u256(num1: bigdecimal::BigDecimal, num2: u256): bigdecimal::BigDecimal
+
+
+
+
+##### Implementation
+
+
+public fun mul_by_u256(num1: BigDecimal, num2: u256): BigDecimal {
+ BigDecimal { scaled: biguint::mul_by_u256(num1.scaled, num2) }
+}
+
+
+
+
+
+
+## Function `mul_by_u256_truncate`
+
+
+
+public fun mul_by_u256_truncate(num1: bigdecimal::BigDecimal, num2: u256): u256
+
+
+
+
+##### Implementation
+
+
+public fun mul_by_u256_truncate(num1: BigDecimal, num2: u256): u256 {
+ truncate_u256(mul_by_u256(num1, num2))
+}
+
+
+
+
+
+
+## Function `mul_by_u256_ceil`
+
+
+
+public fun mul_by_u256_ceil(num1: bigdecimal::BigDecimal, num2: u256): u256
+
+
+
+
+##### Implementation
+
+
+public fun mul_by_u256_ceil(num1: BigDecimal, num2: u256): u256 {
+ ceil_u256(mul_by_u256(num1, num2))
+}
+
+
+
+
+
+
+## Function `div`
+
+
+
+public fun div(num1: bigdecimal::BigDecimal, num2: bigdecimal::BigDecimal): bigdecimal::BigDecimal
+
+
+
+
+##### Implementation
+
+
+public fun div(num1: BigDecimal, num2: BigDecimal): BigDecimal {
+ assert!(
+ !biguint::is_zero(num2.scaled), error::invalid_argument(EDIVISION_BY_ZERO)
+ );
+
+ BigDecimal {
+ scaled: biguint::div(biguint::mul(num1.scaled, f()), num2.scaled)
+ }
+}
+
+
+
+
+
+
+## Function `div_by_u64`
+
+
+
+public fun div_by_u64(num1: bigdecimal::BigDecimal, num2: u64): bigdecimal::BigDecimal
+
+
+
+
+##### Implementation
+
+
+public fun div_by_u64(num1: BigDecimal, num2: u64): BigDecimal {
+ assert!(num2 != 0, error::invalid_argument(EDIVISION_BY_ZERO));
+
+ BigDecimal { scaled: biguint::div_by_u64(num1.scaled, num2) }
+}
+
+
+
+
+
+
+## Function `div_by_u128`
+
+
+
+public fun div_by_u128(num1: bigdecimal::BigDecimal, num2: u128): bigdecimal::BigDecimal
+
+
+
+
+##### Implementation
+
+
+public fun div_by_u128(num1: BigDecimal, num2: u128): BigDecimal {
+ assert!(num2 != 0, error::invalid_argument(EDIVISION_BY_ZERO));
+
+ BigDecimal { scaled: biguint::div_by_u128(num1.scaled, num2) }
+}
+
+
+
+
+
+
+## Function `div_by_u256`
+
+
+
+public fun div_by_u256(num1: bigdecimal::BigDecimal, num2: u256): bigdecimal::BigDecimal
+
+
+
+
+##### Implementation
+
+
+public fun div_by_u256(num1: BigDecimal, num2: u256): BigDecimal {
+ assert!(num2 != 0, error::invalid_argument(EDIVISION_BY_ZERO));
+
+ BigDecimal { scaled: biguint::div_by_u256(num1.scaled, num2) }
+}
+
+
+
+
+
+
+## Function `truncate`
+
+
+
+public fun truncate(num: bigdecimal::BigDecimal): biguint::BigUint
+
+
+
+
+##### Implementation
+
+
+public fun truncate(num: BigDecimal): BigUint {
+ biguint::div(num.scaled, f())
+}
+
+
+
+
+
+
+## Function `truncate_u64`
+
+
+
+public fun truncate_u64(num: bigdecimal::BigDecimal): u64
+
+
+
+
+##### Implementation
+
+
+public fun truncate_u64(num: BigDecimal): u64 {
+ biguint::to_u64(truncate(num))
+}
+
+
+
+
+
+
+## Function `truncate_u128`
+
+
+
+public fun truncate_u128(num: bigdecimal::BigDecimal): u128
+
+
+
+
+##### Implementation
+
+
+public fun truncate_u128(num: BigDecimal): u128 {
+ biguint::to_u128(truncate(num))
+}
+
+
+
+
+
+
+## Function `truncate_u256`
+
+
+
+public fun truncate_u256(num: bigdecimal::BigDecimal): u256
+
+
+
+
+##### Implementation
+
+
+public fun truncate_u256(num: BigDecimal): u256 {
+ biguint::to_u256(truncate(num))
+}
+
+
+
+
+
+
+## Function `round_up`
+
+
+
+public fun round_up(num: bigdecimal::BigDecimal): biguint::BigUint
+
+
+
+
+##### Implementation
+
+
+public fun round_up(num: BigDecimal): BigUint {
+ biguint::div(biguint::add(num.scaled, hf()), f())
+}
+
+
+
+
+
+
+## Function `round_up_u64`
+
+
+
+public fun round_up_u64(num: bigdecimal::BigDecimal): u64
+
+
+
+
+##### Implementation
+
+
+public fun round_up_u64(num: BigDecimal): u64 {
+ biguint::to_u64(round_up(num))
+}
+
+
+
+
+
+
+## Function `round_up_u128`
+
+
+
+public fun round_up_u128(num: bigdecimal::BigDecimal): u128
+
+
+
+
+##### Implementation
+
+
+public fun round_up_u128(num: BigDecimal): u128 {
+ biguint::to_u128(round_up(num))
+}
+
+
+
+
+
+
+## Function `round_up_u256`
+
+
+
+public fun round_up_u256(num: bigdecimal::BigDecimal): u256
+
+
+
+
+##### Implementation
+
+
+public fun round_up_u256(num: BigDecimal): u256 {
+ biguint::to_u256(round_up(num))
+}
+
+
+
+
+
+
+## Function `ceil`
+
+
+
+public fun ceil(num: bigdecimal::BigDecimal): biguint::BigUint
+
+
+
+
+##### Implementation
+
+
+public fun ceil(num: BigDecimal): BigUint {
+ biguint::div(biguint::add(num.scaled, f_1()), f())
+}
+
+
+
+
+
+
+## Function `ceil_u64`
+
+
+
+public fun ceil_u64(num: bigdecimal::BigDecimal): u64
+
+
+
+
+##### Implementation
+
+
+public fun ceil_u64(num: BigDecimal): u64 {
+ biguint::to_u64(ceil(num))
+}
+
+
+
+
+
+
+## Function `ceil_u128`
+
+
+
+public fun ceil_u128(num: bigdecimal::BigDecimal): u128
+
+
+
+
+##### Implementation
+
+
+public fun ceil_u128(num: BigDecimal): u128 {
+ biguint::to_u128(ceil(num))
+}
+
+
+
+
+
+
+## Function `ceil_u256`
+
+
+
+public fun ceil_u256(num: bigdecimal::BigDecimal): u256
+
+
+
+
+##### Implementation
+
+
+public fun ceil_u256(num: BigDecimal): u256 {
+ biguint::to_u256(ceil(num))
+}
+
diff --git a/initia_stdlib/doc/biguint.md b/initia_stdlib/doc/biguint.md
new file mode 100644
index 0000000..2a8038b
--- /dev/null
+++ b/initia_stdlib/doc/biguint.md
@@ -0,0 +1,823 @@
+
+
+
+# Module `0x1::biguint`
+
+
+
+- [Struct `BigUint`](#0x1_biguint_BigUint)
+- [Constants](#@Constants_0)
+- [Function `from_le_bytes`](#0x1_biguint_from_le_bytes)
+- [Function `zero`](#0x1_biguint_zero)
+- [Function `one`](#0x1_biguint_one)
+- [Function `from_u64`](#0x1_biguint_from_u64)
+- [Function `to_u64`](#0x1_biguint_to_u64)
+- [Function `from_u128`](#0x1_biguint_from_u128)
+- [Function `to_u128`](#0x1_biguint_to_u128)
+- [Function `from_u256`](#0x1_biguint_from_u256)
+- [Function `to_u256`](#0x1_biguint_to_u256)
+- [Function `to_le_bytes`](#0x1_biguint_to_le_bytes)
+- [Function `add`](#0x1_biguint_add)
+- [Function `add_by_u64`](#0x1_biguint_add_by_u64)
+- [Function `add_by_u128`](#0x1_biguint_add_by_u128)
+- [Function `add_by_u256`](#0x1_biguint_add_by_u256)
+- [Function `sub`](#0x1_biguint_sub)
+- [Function `sub_by_u64`](#0x1_biguint_sub_by_u64)
+- [Function `sub_by_u128`](#0x1_biguint_sub_by_u128)
+- [Function `sub_by_u256`](#0x1_biguint_sub_by_u256)
+- [Function `mul`](#0x1_biguint_mul)
+- [Function `mul_by_u64`](#0x1_biguint_mul_by_u64)
+- [Function `mul_by_u128`](#0x1_biguint_mul_by_u128)
+- [Function `mul_by_u256`](#0x1_biguint_mul_by_u256)
+- [Function `div`](#0x1_biguint_div)
+- [Function `div_by_u64`](#0x1_biguint_div_by_u64)
+- [Function `div_by_u128`](#0x1_biguint_div_by_u128)
+- [Function `div_by_u256`](#0x1_biguint_div_by_u256)
+- [Function `eq`](#0x1_biguint_eq)
+- [Function `lt`](#0x1_biguint_lt)
+- [Function `le`](#0x1_biguint_le)
+- [Function `gt`](#0x1_biguint_gt)
+- [Function `ge`](#0x1_biguint_ge)
+- [Function `is_zero`](#0x1_biguint_is_zero)
+- [Function `is_one`](#0x1_biguint_is_one)
+
+
+
+
+
+
+
+
+## Struct `BigUint`
+
+
+
+struct BigUint has copy, drop, store
+
+
+
+
+##### Fields
+
+
+
+-
+
bytes: vector<u8>
+
+-
+
+
+
+
+
+
+
+## Constants
+
+
+
+
+
+
+const CAST_OVERFLOW: u64 = 102;
+
+
+
+
+
+
+
+
+const EDIVISION_BY_ZERO: u64 = 101;
+
+
+
+
+
+
+
+
+const INVALID_NUMERIC_TYPE: u64 = 103;
+
+
+
+
+
+
+
+
+const NEGATIVE_RESULT: u64 = 100;
+
+
+
+
+
+
+## Function `from_le_bytes`
+
+Create a new BigUint from little-endian bytes.
+
+
+public fun from_le_bytes(le_bytes: vector<u8>): biguint::BigUint
+
+
+
+
+##### Implementation
+
+
+public fun from_le_bytes(le_bytes: vector<u8>): BigUint {
+ BigUint { bytes: le_bytes }
+}
+
+
+
+
+
+
+## Function `zero`
+
+
+
+public fun zero(): biguint::BigUint
+
+
+
+
+##### Implementation
+
+
+public fun zero(): BigUint {
+ from_u64(0)
+}
+
+
+
+
+
+
+## Function `one`
+
+
+
+public fun one(): biguint::BigUint
+
+
+
+
+##### Implementation
+
+
+public fun one(): BigUint {
+ from_u64(1)
+}
+
+
+
+
+
+
+## Function `from_u64`
+
+
+
+public fun from_u64(num: u64): biguint::BigUint
+
+
+
+
+##### Implementation
+
+
+public fun from_u64(num: u64): BigUint {
+ let num_bytes = new_internal(num);
+ BigUint { bytes: num_bytes }
+}
+
+
+
+
+
+
+## Function `to_u64`
+
+
+
+public fun to_u64(num: biguint::BigUint): u64
+
+
+
+
+##### Implementation
+
+
+public fun to_u64(num: BigUint): u64 {
+ cast_internal<u64>(num.bytes)
+}
+
+
+
+
+
+
+## Function `from_u128`
+
+
+
+public fun from_u128(num: u128): biguint::BigUint
+
+
+
+
+##### Implementation
+
+
+public fun from_u128(num: u128): BigUint {
+ let num_bytes = new_internal(num);
+ BigUint { bytes: num_bytes }
+}
+
+
+
+
+
+
+## Function `to_u128`
+
+
+
+public fun to_u128(num: biguint::BigUint): u128
+
+
+
+
+##### Implementation
+
+
+public fun to_u128(num: BigUint): u128 {
+ cast_internal<u128>(num.bytes)
+}
+
+
+
+
+
+
+## Function `from_u256`
+
+
+
+public fun from_u256(num: u256): biguint::BigUint
+
+
+
+
+##### Implementation
+
+
+public fun from_u256(num: u256): BigUint {
+ let num_bytes = new_internal(num);
+ BigUint { bytes: num_bytes }
+}
+
+
+
+
+
+
+## Function `to_u256`
+
+
+
+public fun to_u256(num: biguint::BigUint): u256
+
+
+
+
+##### Implementation
+
+
+public fun to_u256(num: BigUint): u256 {
+ cast_internal<u256>(num.bytes)
+}
+
+
+
+
+
+
+## Function `to_le_bytes`
+
+
+
+public fun to_le_bytes(num: biguint::BigUint): vector<u8>
+
+
+
+
+##### Implementation
+
+
+public fun to_le_bytes(num: BigUint): vector<u8> {
+ num.bytes
+}
+
+
+
+
+
+
+## Function `add`
+
+
+
+public fun add(num1: biguint::BigUint, num2: biguint::BigUint): biguint::BigUint
+
+
+
+
+##### Implementation
+
+
+public fun add(num1: BigUint, num2: BigUint): BigUint {
+ let result_bytes = add_internal(num1.bytes, num2.bytes);
+ BigUint { bytes: result_bytes }
+}
+
+
+
+
+
+
+## Function `add_by_u64`
+
+
+
+public fun add_by_u64(num1: biguint::BigUint, num2: u64): biguint::BigUint
+
+
+
+
+##### Implementation
+
+
+public fun add_by_u64(num1: BigUint, num2: u64): BigUint {
+ let num2 = from_u64(num2);
+ add(num1, num2)
+}
+
+
+
+
+
+
+## Function `add_by_u128`
+
+
+
+public fun add_by_u128(num1: biguint::BigUint, num2: u128): biguint::BigUint
+
+
+
+
+##### Implementation
+
+
+public fun add_by_u128(num1: BigUint, num2: u128): BigUint {
+ let num2 = from_u128(num2);
+ add(num1, num2)
+}
+
+
+
+
+
+
+## Function `add_by_u256`
+
+
+
+public fun add_by_u256(num1: biguint::BigUint, num2: u256): biguint::BigUint
+
+
+
+
+##### Implementation
+
+
+public fun add_by_u256(num1: BigUint, num2: u256): BigUint {
+ let num2 = from_u256(num2);
+ add(num1, num2)
+}
+
+
+
+
+
+
+## Function `sub`
+
+
+
+public fun sub(num1: biguint::BigUint, num2: biguint::BigUint): biguint::BigUint
+
+
+
+
+##### Implementation
+
+
+public fun sub(num1: BigUint, num2: BigUint): BigUint {
+ let result_bytes = sub_internal(num1.bytes, num2.bytes);
+ BigUint { bytes: result_bytes }
+}
+
+
+
+
+
+
+## Function `sub_by_u64`
+
+
+
+public fun sub_by_u64(num1: biguint::BigUint, num2: u64): biguint::BigUint
+
+
+
+
+##### Implementation
+
+
+public fun sub_by_u64(num1: BigUint, num2: u64): BigUint {
+ let num2 = from_u64(num2);
+ sub(num1, num2)
+}
+
+
+
+
+
+
+## Function `sub_by_u128`
+
+
+
+public fun sub_by_u128(num1: biguint::BigUint, num2: u128): biguint::BigUint
+
+
+
+
+##### Implementation
+
+
+public fun sub_by_u128(num1: BigUint, num2: u128): BigUint {
+ let num2 = from_u128(num2);
+ sub(num1, num2)
+}
+
+
+
+
+
+
+## Function `sub_by_u256`
+
+
+
+public fun sub_by_u256(num1: biguint::BigUint, num2: u256): biguint::BigUint
+
+
+
+
+##### Implementation
+
+
+public fun sub_by_u256(num1: BigUint, num2: u256): BigUint {
+ let num2 = from_u256(num2);
+ sub(num1, num2)
+}
+
+
+
+
+
+
+## Function `mul`
+
+
+
+public fun mul(num1: biguint::BigUint, num2: biguint::BigUint): biguint::BigUint
+
+
+
+
+##### Implementation
+
+
+public fun mul(num1: BigUint, num2: BigUint): BigUint {
+ let result_bytes = mul_internal(num1.bytes, num2.bytes);
+ BigUint { bytes: result_bytes }
+}
+
+
+
+
+
+
+## Function `mul_by_u64`
+
+
+
+public fun mul_by_u64(num1: biguint::BigUint, num2: u64): biguint::BigUint
+
+
+
+
+##### Implementation
+
+
+public fun mul_by_u64(num1: BigUint, num2: u64): BigUint {
+ let num2 = from_u64(num2);
+ mul(num1, num2)
+}
+
+
+
+
+
+
+## Function `mul_by_u128`
+
+
+
+public fun mul_by_u128(num1: biguint::BigUint, num2: u128): biguint::BigUint
+
+
+
+
+##### Implementation
+
+
+public fun mul_by_u128(num1: BigUint, num2: u128): BigUint {
+ let num2 = from_u128(num2);
+ mul(num1, num2)
+}
+
+
+
+
+
+
+## Function `mul_by_u256`
+
+
+
+public fun mul_by_u256(num1: biguint::BigUint, num2: u256): biguint::BigUint
+
+
+
+
+##### Implementation
+
+
+public fun mul_by_u256(num1: BigUint, num2: u256): BigUint {
+ let num2 = from_u256(num2);
+ mul(num1, num2)
+}
+
+
+
+
+
+
+## Function `div`
+
+
+
+public fun div(num1: biguint::BigUint, num2: biguint::BigUint): biguint::BigUint
+
+
+
+
+##### Implementation
+
+
+public fun div(num1: BigUint, num2: BigUint): BigUint {
+ let result_bytes = div_internal(num1.bytes, num2.bytes);
+ BigUint { bytes: result_bytes }
+}
+
+
+
+
+
+
+## Function `div_by_u64`
+
+
+
+public fun div_by_u64(num1: biguint::BigUint, num2: u64): biguint::BigUint
+
+
+
+
+##### Implementation
+
+
+public fun div_by_u64(num1: BigUint, num2: u64): BigUint {
+ let num2 = from_u64(num2);
+ div(num1, num2)
+}
+
+
+
+
+
+
+## Function `div_by_u128`
+
+
+
+public fun div_by_u128(num1: biguint::BigUint, num2: u128): biguint::BigUint
+
+
+
+
+##### Implementation
+
+
+public fun div_by_u128(num1: BigUint, num2: u128): BigUint {
+ let num2 = from_u128(num2);
+ div(num1, num2)
+}
+
+
+
+
+
+
+## Function `div_by_u256`
+
+
+
+public fun div_by_u256(num1: biguint::BigUint, num2: u256): biguint::BigUint
+
+
+
+
+##### Implementation
+
+
+public fun div_by_u256(num1: BigUint, num2: u256): BigUint {
+ let num2 = from_u256(num2);
+ div(num1, num2)
+}
+
+
+
+
+
+
+## Function `eq`
+
+
+
+public fun eq(num1: biguint::BigUint, num2: biguint::BigUint): bool
+
+
+
+
+##### Implementation
+
+
+public fun eq(num1: BigUint, num2: BigUint): bool {
+ num1.bytes == num2.bytes
+}
+
+
+
+
+
+
+## Function `lt`
+
+
+
+public fun lt(num1: biguint::BigUint, num2: biguint::BigUint): bool
+
+
+
+
+##### Implementation
+
+
+public fun lt(num1: BigUint, num2: BigUint): bool {
+ lt_internal(num1.bytes, num2.bytes)
+}
+
+
+
+
+
+
+## Function `le`
+
+
+
+public fun le(num1: biguint::BigUint, num2: biguint::BigUint): bool
+
+
+
+
+##### Implementation
+
+
+public fun le(num1: BigUint, num2: BigUint): bool {
+ le_internal(num1.bytes, num2.bytes)
+}
+
+
+
+
+
+
+## Function `gt`
+
+
+
+public fun gt(num1: biguint::BigUint, num2: biguint::BigUint): bool
+
+
+
+
+##### Implementation
+
+
+public fun gt(num1: BigUint, num2: BigUint): bool {
+ gt_internal(num1.bytes, num2.bytes)
+}
+
+
+
+
+
+
+## Function `ge`
+
+
+
+public fun ge(num1: biguint::BigUint, num2: biguint::BigUint): bool
+
+
+
+
+##### Implementation
+
+
+public fun ge(num1: BigUint, num2: BigUint): bool {
+ ge_internal(num1.bytes, num2.bytes)
+}
+
+
+
+
+
+
+## Function `is_zero`
+
+
+
+public fun is_zero(num: biguint::BigUint): bool
+
+
+
+
+##### Implementation
+
+
+public fun is_zero(num: BigUint): bool {
+ eq(num, zero())
+}
+
+
+
+
+
+
+## Function `is_one`
+
+
+
+public fun is_one(num: biguint::BigUint): bool
+
+
+
+
+##### Implementation
+
+
+public fun is_one(num: BigUint): bool {
+ eq(num, one())
+}
+
diff --git a/initia_stdlib/doc/block.md b/initia_stdlib/doc/block.md
index 133c6d0..e521ad6 100644
--- a/initia_stdlib/doc/block.md
+++ b/initia_stdlib/doc/block.md
@@ -6,6 +6,8 @@
- [Function `get_block_info`](#0x1_block_get_block_info)
+- [Function `get_current_block_height`](#0x1_block_get_current_block_height)
+- [Function `get_current_block_timestamp`](#0x1_block_get_current_block_timestamp)
@@ -23,8 +25,7 @@
-
-Implementation
+##### Implementation
native public fun get_block_info(): (u64, u64);
@@ -32,4 +33,46 @@
-
+
+
+## Function `get_current_block_height`
+
+
+
+#[view]
+public fun get_current_block_height(): u64
+
+
+
+
+##### Implementation
+
+
+public fun get_current_block_height(): u64 {
+ let (height, _) = get_block_info();
+ height
+}
+
+
+
+
+
+
+## Function `get_current_block_timestamp`
+
+
+
+#[view]
+public fun get_current_block_timestamp(): u64
+
+
+
+
+##### Implementation
+
+
+public fun get_current_block_timestamp(): u64 {
+ let (_, timestamp) = get_block_info();
+ timestamp
+}
+
diff --git a/initia_stdlib/doc/code.md b/initia_stdlib/doc/code.md
index bbb0dd6..dceb074 100644
--- a/initia_stdlib/doc/code.md
+++ b/initia_stdlib/doc/code.md
@@ -11,17 +11,20 @@
- [Struct `ModulePublishedEvent`](#0x1_code_ModulePublishedEvent)
- [Constants](#@Constants_0)
- [Function `can_change_upgrade_policy_to`](#0x1_code_can_change_upgrade_policy_to)
-- [Function `init_module`](#0x1_code_init_module)
+- [Function `allowed_publishers`](#0x1_code_allowed_publishers)
+- [Function `total_modules`](#0x1_code_total_modules)
- [Function `init_genesis`](#0x1_code_init_genesis)
- [Function `set_allowed_publishers`](#0x1_code_set_allowed_publishers)
-- [Function `assert_allowed`](#0x1_code_assert_allowed)
+- [Function `freeze_code_object`](#0x1_code_freeze_code_object)
- [Function `publish`](#0x1_code_publish)
-- [Function `request_publish`](#0x1_code_request_publish)
use 0x1::error;
use 0x1::event;
+use 0x1::object;
+use 0x1::option;
use 0x1::signer;
+use 0x1::simple_map;
use 0x1::string;
use 0x1::table;
use 0x1::vector;
@@ -40,8 +43,7 @@
-
-Fields
+##### Fields
@@ -52,11 +54,15 @@
It is a list of addresses with permission to distribute contracts,
and an empty list is interpreted as allowing anyone to distribute.
+-
+
total_modules: u64
+
+-
+ The total number of modules published.
+
-
-
## Resource `MetadataStore`
@@ -68,8 +74,7 @@
-
-Fields
+##### Fields
@@ -82,8 +87,6 @@
-
-
## Struct `ModuleMetadata`
@@ -96,8 +99,7 @@ Describes an upgrade policy
-
-Fields
+##### Fields
@@ -110,8 +112,6 @@ Describes an upgrade policy
-
-
## Struct `ModulePublishedEvent`
@@ -124,8 +124,7 @@ Describes an upgrade policy
-
-Fields
+##### Fields
@@ -144,13 +143,31 @@ Describes an upgrade policy
-
-
## Constants
+
+
+code_object
does not exist.
+
+
+const ECODE_OBJECT_DOES_NOT_EXIST: u64 = 9;
+
+
+
+
+
+
+The module ID is duplicated.
+
+
+const EDUPLICATE_MODULE_ID: u64 = 7;
+
+
+
+
allowed_publishers argument is invalid.
@@ -181,6 +198,16 @@ The operation is expected to be executed by chain signer.
+
+
+Not the owner of the package registry.
+
+
+const ENOT_PACKAGE_OWNER: u64 = 8;
+
+
+
+
Cannot upgrade an immutable package.
@@ -232,16 +259,6 @@ Whether the modules in the package are immutable and cannot be upgraded.
-
-
-The upgrade policy is unspecified.
-
-
-const UPGRADE_POLICY_UNSPECIFIED: u8 = 0;
-
-
-
-
## Function `can_change_upgrade_policy_to`
@@ -255,8 +272,7 @@ strengthened but not weakened.
-
-Implementation
+##### Implementation
public fun can_change_upgrade_policy_to(from: u8, to: u8): bool {
@@ -266,33 +282,51 @@ strengthened but not weakened.
-
-
-
+
-## Function `init_module`
+## Function `allowed_publishers`
-fun init_module(chain: &signer)
+#[view]
+public fun allowed_publishers(): vector<address>
-
-Implementation
+##### Implementation
-fun init_module(chain: &signer) {
- move_to(chain, ModuleStore {
- allowed_publishers: vector[],
- });
+public fun allowed_publishers(): vector<address> acquires ModuleStore {
+ let module_store = borrow_global<ModuleStore>(@initia_std);
+ module_store.allowed_publishers
}
-
+
+
+## Function `total_modules`
+
+
+
+#[view]
+public fun total_modules(): u64
+
+
+
+
+##### Implementation
+
+
+public fun total_modules(): u64 acquires ModuleStore {
+ let module_store = borrow_global<ModuleStore>(@initia_std);
+ module_store.total_modules
+}
+
+
+
@@ -305,38 +339,41 @@ strengthened but not weakened.
-
-Implementation
+##### Implementation
public entry fun init_genesis(
- chain: &signer,
- module_ids: vector<String>,
- allowed_publishers: vector<address>,
+ chain: &signer, module_ids: vector<String>, allowed_publishers: vector<address>
) acquires ModuleStore {
- assert!(signer::address_of(chain) == @initia_std, error::permission_denied(EINVALID_CHAIN_OPERATOR));
+ assert!(
+ signer::address_of(chain) == @initia_std,
+ error::permission_denied(EINVALID_CHAIN_OPERATOR)
+ );
let metadata_table = table::new<String, ModuleMetadata>();
- vector::for_each_ref(&module_ids,
+ vector::for_each_ref(
+ &module_ids,
|module_id| {
- table::add<String, ModuleMetadata>(&mut metadata_table, *module_id, ModuleMetadata {
- upgrade_policy: UPGRADE_POLICY_COMPATIBLE,
- });
+ table::add<String, ModuleMetadata>(
+ &mut metadata_table,
+ *module_id,
+ ModuleMetadata { upgrade_policy: UPGRADE_POLICY_COMPATIBLE }
+ );
}
);
- move_to<MetadataStore>(chain, MetadataStore {
- metadata: metadata_table,
- });
+ move_to<MetadataStore>(
+ chain,
+ MetadataStore { metadata: metadata_table }
+ );
set_allowed_publishers(chain, allowed_publishers);
+ increase_total_modules(vector::length(&module_ids));
}
-
-
## Function `set_allowed_publishers`
@@ -348,12 +385,16 @@ strengthened but not weakened.
-
-Implementation
+##### Implementation
-public entry fun set_allowed_publishers(chain: &signer, allowed_publishers: vector<address>) acquires ModuleStore {
- assert!(signer::address_of(chain) == @initia_std, error::permission_denied(EINVALID_CHAIN_OPERATOR));
+public entry fun set_allowed_publishers(
+ chain: &signer, allowed_publishers: vector<address>
+) acquires ModuleStore {
+ assert!(
+ signer::address_of(chain) == @initia_std,
+ error::permission_denied(EINVALID_CHAIN_OPERATOR)
+ );
assert_allowed(&allowed_publishers, @initia_std);
let module_store = borrow_global_mut<ModuleStore>(@initia_std);
@@ -363,35 +404,48 @@ strengthened but not weakened.
-
+
-
+## Function `freeze_code_object`
-## Function `assert_allowed`
-
-fun assert_allowed(allowed_publishers: &vector<address>, addr: address)
+public fun freeze_code_object(publisher: &signer, code_object: object::Object<code::MetadataStore>)
-
-Implementation
+##### Implementation
-fun assert_allowed(allowed_publishers: &vector<address>, addr: address) {
+public fun freeze_code_object(
+ publisher: &signer, code_object: Object<MetadataStore>
+) acquires MetadataStore {
+ let code_object_addr = object::object_address(&code_object);
+ assert!(
+ exists<MetadataStore>(code_object_addr),
+ error::not_found(ECODE_OBJECT_DOES_NOT_EXIST)
+ );
assert!(
- vector::is_empty(allowed_publishers) || vector::contains(allowed_publishers, &addr),
- error::invalid_argument(EINVALID_ALLOWED_PUBLISHERS),
- )
+ object::is_owner(code_object, signer::address_of(publisher)),
+ error::permission_denied(ENOT_PACKAGE_OWNER)
+ );
+
+ let registry = borrow_global_mut<MetadataStore>(code_object_addr);
+ let iter = table::iter_mut(
+ &mut registry.metadata, option::none(), option::none(), 1
+ );
+ loop {
+ if (!table::prepare_mut(iter)) { break };
+
+ let (_, metadata) = table::next_mut(iter);
+ metadata.upgrade_policy = UPGRADE_POLICY_IMMUTABLE;
+ }
}
-
-
## Function `publish`
@@ -405,93 +459,95 @@ package.
-
-Implementation
+##### Implementation
public entry fun publish(
owner: &signer,
module_ids: vector<String>, // 0x1::coin
code: vector<vector<u8>>,
- upgrade_policy: u8,
+ upgrade_policy: u8
) acquires ModuleStore, MetadataStore {
// Disallow incompatible upgrade mode. Governance can decide later if this should be reconsidered.
- assert!(vector::length(&code) == vector::length(&module_ids), error::invalid_argument(EINVALID_ARGUMENTS));
+ assert!(
+ vector::length(&code) == vector::length(&module_ids),
+ error::invalid_argument(EINVALID_ARGUMENTS)
+ );
+
+ // duplication check
+ let module_ids_set = simple_map::create<String, bool>();
+ vector::for_each_ref(
+ &module_ids,
+ |module_id| {
+ assert!(
+ !simple_map::contains_key(&module_ids_set, module_id),
+ error::invalid_argument(EDUPLICATE_MODULE_ID)
+ );
+ simple_map::add(
+ &mut module_ids_set,
+ *module_id,
+ true
+ );
+ }
+ );
// Check whether arbitrary publish is allowed or not.
let module_store = borrow_global_mut<ModuleStore>(@initia_std);
assert!(
- upgrade_policy > UPGRADE_POLICY_UNSPECIFIED,
- error::invalid_argument(EUPGRADE_POLICY_UNSPECIFIED),
+ upgrade_policy == UPGRADE_POLICY_COMPATIBLE
+ || upgrade_policy == UPGRADE_POLICY_IMMUTABLE,
+ error::invalid_argument(EUPGRADE_POLICY_UNSPECIFIED)
);
let addr = signer::address_of(owner);
assert_allowed(&module_store.allowed_publishers, addr);
if (!exists<MetadataStore>(addr)) {
- move_to<MetadataStore>(owner, MetadataStore {
- metadata: table::new(),
- });
+ move_to<MetadataStore>(
+ owner,
+ MetadataStore { metadata: table::new() }
+ );
};
// Check upgradability
let metadata_table = &mut borrow_global_mut<MetadataStore>(addr).metadata;
- vector::for_each_ref(&module_ids,
+ vector::for_each_ref(
+ &module_ids,
|module_id| {
if (table::contains<String, ModuleMetadata>(metadata_table, *module_id)) {
- let metadata = table::borrow_mut<String, ModuleMetadata>(metadata_table, *module_id);
- assert!(metadata.upgrade_policy < UPGRADE_POLICY_IMMUTABLE,
- error::invalid_argument(EUPGRADE_IMMUTABLE));
- assert!(can_change_upgrade_policy_to(metadata.upgrade_policy, upgrade_policy),
- error::invalid_argument(EUPGRADE_WEAKER_POLICY));
+ let metadata =
+ table::borrow_mut<String, ModuleMetadata>(
+ metadata_table, *module_id
+ );
+ assert!(
+ metadata.upgrade_policy < UPGRADE_POLICY_IMMUTABLE,
+ error::invalid_argument(EUPGRADE_IMMUTABLE)
+ );
+ assert!(
+ can_change_upgrade_policy_to(
+ metadata.upgrade_policy,
+ upgrade_policy
+ ),
+ error::invalid_argument(EUPGRADE_WEAKER_POLICY)
+ );
metadata.upgrade_policy = upgrade_policy;
} else {
- table::add<String, ModuleMetadata>(metadata_table, *module_id, ModuleMetadata {
- upgrade_policy,
- });
+ table::add<String, ModuleMetadata>(
+ metadata_table,
+ *module_id,
+ ModuleMetadata { upgrade_policy }
+ );
};
- event::emit(ModulePublishedEvent {
- module_id: *module_id,
- upgrade_policy,
- });
+ event::emit(
+ ModulePublishedEvent { module_id: *module_id, upgrade_policy }
+ );
}
);
// Request publish
- request_publish(addr, module_ids, code, upgrade_policy)
+ increase_total_modules(vector::length(&module_ids));
+ request_publish(addr, module_ids, code)
}
-
-
-
-
-
-
-
-## Function `request_publish`
-
-Native function to initiate module loading
-
-
-fun request_publish(owner: address, expected_modules: vector<string::String>, code: vector<vector<u8>>, policy: u8)
-
-
-
-
-
-Implementation
-
-
-native fun request_publish(
- owner: address,
- expected_modules: vector<String>,
- code: vector<vector<u8>>,
- policy: u8
-);
-
-
-
-
-
diff --git a/initia_stdlib/doc/coin.md b/initia_stdlib/doc/coin.md
index a7e3c4b..c50801a 100644
--- a/initia_stdlib/doc/coin.md
+++ b/initia_stdlib/doc/coin.md
@@ -12,6 +12,8 @@ TODO - make is_module_account or some blacklist from freeze.
- [Struct `BurnCapability`](#0x1_coin_BurnCapability)
- [Struct `FreezeCapability`](#0x1_coin_FreezeCapability)
- [Constants](#@Constants_0)
+- [Function `sudo_transfer`](#0x1_coin_sudo_transfer)
+- [Function `sudo_deposit`](#0x1_coin_sudo_deposit)
- [Function `initialize`](#0x1_coin_initialize)
- [Function `initialize_and_generate_extend_ref`](#0x1_coin_initialize_and_generate_extend_ref)
- [Function `withdraw`](#0x1_coin_withdraw)
@@ -32,7 +34,6 @@ TODO - make is_module_account or some blacklist from freeze.
- [Function `decimals`](#0x1_coin_decimals)
- [Function `metadata_address`](#0x1_coin_metadata_address)
- [Function `metadata`](#0x1_coin_metadata)
-- [Function `is_coin_initialized`](#0x1_coin_is_coin_initialized)
- [Function `is_coin`](#0x1_coin_is_coin)
- [Function `is_coin_by_symbol`](#0x1_coin_is_coin_by_symbol)
- [Function `metadata_to_denom`](#0x1_coin_metadata_to_denom)
@@ -40,6 +41,7 @@ TODO - make is_module_account or some blacklist from freeze.
use 0x1::bcs;
+use 0x1::error;
use 0x1::event;
use 0x1::from_bcs;
use 0x1::fungible_asset;
@@ -47,6 +49,7 @@ TODO - make is_module_account or some blacklist from freeze.
use 0x1::object;
use 0x1::option;
use 0x1::primary_fungible_store;
+use 0x1::signer;
use 0x1::string;
@@ -63,8 +66,7 @@ TODO - make is_module_account or some blacklist from freeze.
-
-Fields
+##### Fields
@@ -89,8 +91,6 @@ TODO - make is_module_account or some blacklist from freeze.
-
-
## Struct `CoinCreatedEvent`
@@ -103,8 +103,7 @@ TODO - make is_module_account or some blacklist from freeze.
-
-Fields
+##### Fields
@@ -117,8 +116,6 @@ TODO - make is_module_account or some blacklist from freeze.
-
-
## Struct `MintCapability`
@@ -130,8 +127,7 @@ TODO - make is_module_account or some blacklist from freeze.
-
-Fields
+##### Fields
@@ -144,8 +140,6 @@ TODO - make is_module_account or some blacklist from freeze.
-
-
## Struct `BurnCapability`
@@ -157,8 +151,7 @@ TODO - make is_module_account or some blacklist from freeze.
-
-Fields
+##### Fields
@@ -171,8 +164,6 @@ TODO - make is_module_account or some blacklist from freeze.
-
-
## Struct `FreezeCapability`
@@ -184,8 +175,7 @@ TODO - make is_module_account or some blacklist from freeze.
-
-Fields
+##### Fields
@@ -198,8 +188,6 @@ TODO - make is_module_account or some blacklist from freeze.
-
-
## Constants
@@ -225,6 +213,67 @@ Only fungible asset metadata owner can make changes.
+
+
+
+
+const EUNAUTHORIZED: u64 = 1;
+
+
+
+
+
+
+## Function `sudo_transfer`
+
+
+
+public entry fun sudo_transfer(chain: &signer, sender: &signer, recipient: address, metadata: object::Object<fungible_asset::Metadata>, amount: u64)
+
+
+
+
+##### Implementation
+
+
+public entry fun sudo_transfer(
+ chain: &signer,
+ sender: &signer,
+ recipient: address,
+ metadata: Object<Metadata>,
+ amount: u64
+) {
+ check_sudo(chain);
+
+ primary_fungible_store::sudo_transfer(sender, metadata, recipient, amount)
+}
+
+
+
+
+
+
+## Function `sudo_deposit`
+
+
+
+public(friend) fun sudo_deposit(account_addr: address, fa: fungible_asset::FungibleAsset)
+
+
+
+
+##### Implementation
+
+
+public(friend) fun sudo_deposit(
+ account_addr: address, fa: FungibleAsset
+) {
+ primary_fungible_store::sudo_deposit(account_addr, fa)
+}
+
+
+
+
## Function `initialize`
@@ -236,28 +285,28 @@ Only fungible asset metadata owner can make changes.
-
-Implementation
+##### Implementation
-public fun initialize (
+public fun initialize(
creator: &signer,
maximum_supply: Option<u128>,
name: String,
symbol: String,
decimals: u8,
icon_uri: String,
- project_uri: String,
+ project_uri: String
): (MintCapability, BurnCapability, FreezeCapability) {
- let (mint_cap, burn_cap, freeze_cap, _) = initialize_and_generate_extend_ref(
- creator,
- maximum_supply,
- name,
- symbol,
- decimals,
- icon_uri,
- project_uri,
- );
+ let (mint_cap, burn_cap, freeze_cap, _) =
+ initialize_and_generate_extend_ref(
+ creator,
+ maximum_supply,
+ name,
+ symbol,
+ decimals,
+ icon_uri,
+ project_uri
+ );
(mint_cap, burn_cap, freeze_cap)
}
@@ -265,8 +314,6 @@ Only fungible asset metadata owner can make changes.
-
-
## Function `initialize_and_generate_extend_ref`
@@ -278,21 +325,24 @@ Only fungible asset metadata owner can make changes.
-
-Implementation
+##### Implementation
-public fun initialize_and_generate_extend_ref (
+public fun initialize_and_generate_extend_ref(
creator: &signer,
maximum_supply: Option<u128>,
name: String,
symbol: String,
decimals: u8,
icon_uri: String,
- project_uri: String,
+ project_uri: String
): (MintCapability, BurnCapability, FreezeCapability, ExtendRef) {
// create object for fungible asset metadata
- let constructor_ref = &object::create_named_object(creator, *string::bytes(&symbol), false);
+ let constructor_ref =
+ &object::create_named_object(
+ creator,
+ *string::bytes(&symbol)
+ );
primary_fungible_store::create_primary_store_enabled_fungible_asset(
constructor_ref,
@@ -301,7 +351,7 @@ Only fungible asset metadata owner can make changes.
symbol,
decimals,
icon_uri,
- project_uri,
+ project_uri
);
let mint_ref = fungible_asset::generate_mint_ref(constructor_ref);
@@ -309,26 +359,26 @@ Only fungible asset metadata owner can make changes.
let transfer_ref = fungible_asset::generate_transfer_ref(constructor_ref);
let object_signer = object::generate_signer(constructor_ref);
- move_to(&object_signer, ManagingRefs {
- mint_ref,
- burn_ref,
- transfer_ref,
- });
+ move_to(
+ &object_signer,
+ ManagingRefs { mint_ref, burn_ref, transfer_ref }
+ );
let metadata_addr = object::address_from_constructor_ref(constructor_ref);
- event::emit(CoinCreatedEvent {
- metadata_addr,
- });
+ event::emit(CoinCreatedEvent { metadata_addr });
let metadata = object::object_from_constructor_ref<Metadata>(constructor_ref);
- (MintCapability { metadata }, BurnCapability { metadata }, FreezeCapability { metadata }, object::generate_extend_ref(constructor_ref))
+ (
+ MintCapability { metadata },
+ BurnCapability { metadata },
+ FreezeCapability { metadata },
+ object::generate_extend_ref(constructor_ref)
+ )
}
-
-
## Function `withdraw`
@@ -340,14 +390,11 @@ Only fungible asset metadata owner can make changes.
-
-Implementation
+##### Implementation
-public fun withdraw (
- account: &signer,
- metadata: Object<Metadata>,
- amount: u64,
+public fun withdraw(
+ account: &signer, metadata: Object<Metadata>, amount: u64
): FungibleAsset {
primary_fungible_store::withdraw(account, metadata, amount)
}
@@ -355,8 +402,6 @@ Only fungible asset metadata owner can make changes.
-
-
## Function `deposit`
@@ -368,22 +413,16 @@ Only fungible asset metadata owner can make changes.
-
-Implementation
+##### Implementation
-public fun deposit (
- account_addr: address,
- fa: FungibleAsset,
-) {
+public fun deposit(account_addr: address, fa: FungibleAsset) {
primary_fungible_store::deposit(account_addr, fa)
}
-
-
## Function `transfer`
@@ -395,15 +434,14 @@ Only fungible asset metadata owner can make changes.
-
-Implementation
+##### Implementation
-public entry fun transfer (
+public entry fun transfer(
sender: &signer,
recipient: address,
metadata: Object<Metadata>,
- amount: u64,
+ amount: u64
) {
primary_fungible_store::transfer(sender, metadata, recipient, amount)
}
@@ -411,8 +449,6 @@ Only fungible asset metadata owner can make changes.
-
-
## Function `mint`
@@ -425,18 +461,17 @@ Mint FAs as the owner of metadat object.
-
-Implementation
+##### Implementation
-public fun mint(
- mint_cap: &MintCapability,
- amount: u64,
-): FungibleAsset acquires ManagingRefs {
+public fun mint(mint_cap: &MintCapability, amount: u64): FungibleAsset acquires ManagingRefs {
let metadata = mint_cap.metadata;
- let metadata_addr = object::object_address(metadata);
+ let metadata_addr = object::object_address(&metadata);
- assert!(exists<ManagingRefs>(metadata_addr), ERR_MANAGING_REFS_NOT_FOUND);
+ assert!(
+ exists<ManagingRefs>(metadata_addr),
+ ERR_MANAGING_REFS_NOT_FOUND
+ );
let refs = borrow_global<ManagingRefs>(metadata_addr);
fungible_asset::mint(&refs.mint_ref, amount)
@@ -445,8 +480,6 @@ Mint FAs as the owner of metadat object.
-
-
## Function `mint_to`
@@ -459,19 +492,19 @@ Mint FAs as the owner of metadat object to the primary fungible store of the giv
-
-Implementation
+##### Implementation
public fun mint_to(
- mint_cap: &MintCapability,
- recipient: address,
- amount: u64,
+ mint_cap: &MintCapability, recipient: address, amount: u64
) acquires ManagingRefs {
let metadata = mint_cap.metadata;
- let metadata_addr = object::object_address(metadata);
+ let metadata_addr = object::object_address(&metadata);
- assert!(exists<ManagingRefs>(metadata_addr), ERR_MANAGING_REFS_NOT_FOUND);
+ assert!(
+ exists<ManagingRefs>(metadata_addr),
+ ERR_MANAGING_REFS_NOT_FOUND
+ );
let refs = borrow_global<ManagingRefs>(metadata_addr);
primary_fungible_store::mint(&refs.mint_ref, recipient, amount)
@@ -480,8 +513,6 @@ Mint FAs as the owner of metadat object to the primary fungible store of the giv
-
-
## Function `burn`
@@ -494,18 +525,17 @@ Burn FAs as the owner of metadat object.
-
-Implementation
+##### Implementation
-public fun burn(
- burn_cap: &BurnCapability,
- fa: FungibleAsset,
-) acquires ManagingRefs {
+public fun burn(burn_cap: &BurnCapability, fa: FungibleAsset) acquires ManagingRefs {
let metadata = burn_cap.metadata;
- let metadata_addr = object::object_address(metadata);
+ let metadata_addr = object::object_address(&metadata);
- assert!(exists<ManagingRefs>(metadata_addr), ERR_MANAGING_REFS_NOT_FOUND);
+ assert!(
+ exists<ManagingRefs>(metadata_addr),
+ ERR_MANAGING_REFS_NOT_FOUND
+ );
let refs = borrow_global<ManagingRefs>(metadata_addr);
fungible_asset::burn(&refs.burn_ref, fa)
@@ -514,8 +544,6 @@ Burn FAs as the owner of metadat object.
-
-
## Function `freeze_coin_store`
@@ -528,28 +556,31 @@ Freeze the primary store of an account.
-
-Implementation
+##### Implementation
public fun freeze_coin_store(
- freeze_cap: &FreezeCapability,
- account_addr: address,
+ freeze_cap: &FreezeCapability, account_addr: address
) acquires ManagingRefs {
let metadata = freeze_cap.metadata;
- let metadata_addr = object::object_address(metadata);
+ let metadata_addr = object::object_address(&metadata);
- assert!(exists<ManagingRefs>(metadata_addr), ERR_MANAGING_REFS_NOT_FOUND);
+ assert!(
+ exists<ManagingRefs>(metadata_addr),
+ ERR_MANAGING_REFS_NOT_FOUND
+ );
let refs = borrow_global<ManagingRefs>(metadata_addr);
- primary_fungible_store::set_frozen_flag(&refs.transfer_ref, account_addr, true)
+ primary_fungible_store::set_frozen_flag(
+ &refs.transfer_ref,
+ account_addr,
+ true
+ )
}
-
-
## Function `unfreeze_coin_store`
@@ -562,28 +593,31 @@ Unfreeze the primary store of an account.
-
-Implementation
+##### Implementation
public fun unfreeze_coin_store(
- freeze_cap: &FreezeCapability,
- account_addr: address,
+ freeze_cap: &FreezeCapability, account_addr: address
) acquires ManagingRefs {
let metadata = freeze_cap.metadata;
- let metadata_addr = object::object_address(metadata);
+ let metadata_addr = object::object_address(&metadata);
- assert!(exists<ManagingRefs>(metadata_addr), ERR_MANAGING_REFS_NOT_FOUND);
+ assert!(
+ exists<ManagingRefs>(metadata_addr),
+ ERR_MANAGING_REFS_NOT_FOUND
+ );
let refs = borrow_global<ManagingRefs>(metadata_addr);
- primary_fungible_store::set_frozen_flag(&refs.transfer_ref, account_addr, false)
+ primary_fungible_store::set_frozen_flag(
+ &refs.transfer_ref,
+ account_addr,
+ false
+ )
}
-
-
## Function `balance`
@@ -596,8 +630,7 @@ Unfreeze the primary store of an account.
-
-Implementation
+##### Implementation
public fun balance(account: address, metadata: Object<Metadata>): u64 {
@@ -607,8 +640,6 @@ Unfreeze the primary store of an account.
-
-
## Function `is_frozen`
@@ -621,8 +652,7 @@ Unfreeze the primary store of an account.
-
-Implementation
+##### Implementation
public fun is_frozen(account: address, metadata: Object<Metadata>): bool {
@@ -632,8 +662,6 @@ Unfreeze the primary store of an account.
-
-
## Function `balances`
@@ -646,14 +674,11 @@ Unfreeze the primary store of an account.
-
-Implementation
+##### Implementation
public fun balances(
- account: address,
- start_after: Option<address>,
- limit: u8,
+ account: address, start_after: Option<address>, limit: u8
): (vector<Object<Metadata>>, vector<u64>) {
primary_fungible_store::balances(account, start_after, limit)
}
@@ -661,8 +686,6 @@ Unfreeze the primary store of an account.
-
-
## Function `supply`
@@ -676,8 +699,7 @@ Get the current supply from the metadata
object.
-
-Implementation
+##### Implementation
public fun supply(metadata: Object<Metadata>): Option<u128> {
@@ -687,8 +709,6 @@ Get the current supply from the metadata
object.
-
-
## Function `maximum`
@@ -702,8 +722,7 @@ Get the maximum supply from the metadata
object.
-
-Implementation
+##### Implementation
public fun maximum(metadata: Object<Metadata>): Option<u128> {
@@ -713,8 +732,6 @@ Get the maximum supply from the metadata
object.
-
-
## Function `name`
@@ -728,8 +745,7 @@ Get the name of the fungible asset from the metadata
object.
-
-Implementation
+##### Implementation
public fun name(metadata: Object<Metadata>): String {
@@ -739,8 +755,6 @@ Get the name of the fungible asset from the metadata
object.
-
-
## Function `symbol`
@@ -754,8 +768,7 @@ Get the symbol of the fungible asset from the metadata
object.
-
-Implementation
+##### Implementation
public fun symbol(metadata: Object<Metadata>): String {
@@ -765,8 +778,6 @@ Get the symbol of the fungible asset from the metadata
object.
-
-
## Function `decimals`
@@ -780,8 +791,7 @@ Get the decimals from the metadata
object.
-
-Implementation
+##### Implementation
public fun decimals(metadata: Object<Metadata>): u8 {
@@ -791,8 +801,6 @@ Get the decimals from the metadata
object.
-
-
## Function `metadata_address`
@@ -805,19 +813,16 @@ Get the decimals from the metadata
object.
-
-Implementation
+##### Implementation
public fun metadata_address(creator: address, symbol: String): address {
- object::create_object_address(creator, *string::bytes(&symbol))
+ object::create_object_address(&creator, *string::bytes(&symbol))
}
-
-
## Function `metadata`
@@ -830,8 +835,7 @@ Get the decimals from the metadata
object.
-
-Implementation
+##### Implementation
public fun metadata(creator: address, symbol: String): Object<Metadata> {
@@ -841,34 +845,6 @@ Get the decimals from the metadata
object.
-
-
-
-
-## Function `is_coin_initialized`
-
-
-
-#[view]
-public fun is_coin_initialized(metadata: object::Object<fungible_asset::Metadata>): bool
-
-
-
-
-
-Implementation
-
-
-public fun is_coin_initialized(metadata: Object<Metadata>): bool {
- let metadata_addr = object::object_address(metadata);
- exists<ManagingRefs>(metadata_addr)
-}
-
-
-
-
-
-
## Function `is_coin`
@@ -881,8 +857,7 @@ Get the decimals from the metadata
object.
-
-Implementation
+##### Implementation
public fun is_coin(metadata_addr: address): bool {
@@ -892,8 +867,6 @@ Get the decimals from the metadata
object.
-
-
## Function `is_coin_by_symbol`
@@ -906,8 +879,7 @@ Get the decimals from the metadata
object.
-
-Implementation
+##### Implementation
public fun is_coin_by_symbol(creator: address, symbol: String): bool {
@@ -918,8 +890,6 @@ Get the decimals from the metadata
object.
-
-
## Function `metadata_to_denom`
@@ -932,12 +902,11 @@ Get the decimals from the metadata
object.
-
-Implementation
+##### Implementation
public fun metadata_to_denom(metadata: Object<Metadata>): String {
- let metadata_addr = object::object_address(metadata);
+ let metadata_addr = object::object_address(&metadata);
let symbol = symbol(metadata);
let std_metadata_addr = metadata_address(@initia_std, symbol);
@@ -955,8 +924,6 @@ Get the decimals from the metadata
object.
-
-
## Function `denom_to_metadata`
@@ -969,23 +936,20 @@ Get the decimals from the metadata
object.
-
-Implementation
+##### Implementation
public fun denom_to_metadata(denom: String): Object<Metadata> {
- let addr = if (string::length(&denom) > 5 && &b"move/" == string::bytes(&string::sub_string(&denom, 0, 5))) {
- let len = string::length(&denom);
- let hex_string = string::sub_string(&denom, 5, len);
- from_bcs::to_address(hex::decode_string(&hex_string))
- } else {
- metadata_address(@initia_std, denom)
- };
+ let addr =
+ if (string::length(&denom) > 5
+ && &b"move/" == string::bytes(&string::sub_string(&denom, 0, 5))) {
+ let len = string::length(&denom);
+ let hex_string = string::sub_string(&denom, 5, len);
+ from_bcs::to_address(hex::decode_string(&hex_string))
+ } else {
+ metadata_address(@initia_std, denom)
+ };
object::address_to_object(addr)
}
-
-
-
-
diff --git a/initia_stdlib/doc/collection.md b/initia_stdlib/doc/collection.md
index 73f535e..4949e3b 100644
--- a/initia_stdlib/doc/collection.md
+++ b/initia_stdlib/doc/collection.md
@@ -35,15 +35,11 @@ require adding the field original_name.
- [Constants](#@Constants_0)
- [Function `create_fixed_collection`](#0x1_collection_create_fixed_collection)
- [Function `create_unlimited_collection`](#0x1_collection_create_unlimited_collection)
-- [Function `create_untracked_collection`](#0x1_collection_create_untracked_collection)
-- [Function `create_collection_internal`](#0x1_collection_create_collection_internal)
- [Function `create_collection_address`](#0x1_collection_create_collection_address)
- [Function `create_collection_seed`](#0x1_collection_create_collection_seed)
- [Function `increment_supply`](#0x1_collection_increment_supply)
- [Function `decrement_supply`](#0x1_collection_decrement_supply)
- [Function `generate_mutator_ref`](#0x1_collection_generate_mutator_ref)
-- [Function `check_collection_exists`](#0x1_collection_check_collection_exists)
-- [Function `borrow`](#0x1_collection_borrow)
- [Function `count`](#0x1_collection_count)
- [Function `creator`](#0x1_collection_creator)
- [Function `description`](#0x1_collection_description)
@@ -51,7 +47,6 @@ require adding the field original_name.
- [Function `uri`](#0x1_collection_uri)
- [Function `nfts`](#0x1_collection_nfts)
- [Function `decompose_nft_response`](#0x1_collection_decompose_nft_response)
-- [Function `borrow_mut`](#0x1_collection_borrow_mut)
- [Function `set_description`](#0x1_collection_set_description)
- [Function `set_uri`](#0x1_collection_set_uri)
@@ -80,8 +75,7 @@ Represents the common fields for a collection.
-
-Fields
+##### Fields
@@ -119,8 +113,6 @@ Represents the common fields for a collection.
-
-
## Struct `MutatorRef`
@@ -133,8 +125,7 @@ This enables mutating description and URI by higher level services.
-
-Fields
+##### Fields
@@ -147,8 +138,6 @@ This enables mutating description and URI by higher level services.
-
-
## Struct `MutationEvent`
@@ -163,8 +152,7 @@ directly understand the behavior in a writeset.
-
-Fields
+##### Fields
@@ -195,8 +183,6 @@ directly understand the behavior in a writeset.
-
-
## Resource `FixedSupply`
@@ -210,8 +196,7 @@ and adding events and supply tracking to a collection.
-
-Fields
+##### Fields
@@ -236,8 +221,6 @@ and adding events and supply tracking to a collection.
-
-
## Resource `UnlimitedSupply`
@@ -250,8 +233,7 @@ Unlimited supply tracker, this is useful for adding events and supply tracking t
-
-Fields
+##### Fields
@@ -270,8 +252,6 @@ Unlimited supply tracker, this is useful for adding events and supply tracking t
-
-
## Struct `NftResponse`
@@ -283,8 +263,7 @@ Unlimited supply tracker, this is useful for adding events and supply tracking t
-
-Fields
+##### Fields
@@ -303,8 +282,6 @@ Unlimited supply tracker, this is useful for adding events and supply tracking t
-
-
## Struct `CreateCollectionEvent`
@@ -317,8 +294,7 @@ Unlimited supply tracker, this is useful for adding events and supply tracking t
-
-Fields
+##### Fields
@@ -343,8 +319,6 @@ Unlimited supply tracker, this is useful for adding events and supply tracking t
-
-
## Struct `BurnEvent`
@@ -357,8 +331,7 @@ Unlimited supply tracker, this is useful for adding events and supply tracking t
-
-Fields
+##### Fields
@@ -383,8 +356,6 @@ Unlimited supply tracker, this is useful for adding events and supply tracking t
-
-
## Struct `MintEvent`
@@ -397,8 +368,7 @@ Unlimited supply tracker, this is useful for adding events and supply tracking t
-
-Fields
+##### Fields
@@ -423,8 +393,6 @@ Unlimited supply tracker, this is useful for adding events and supply tracking t
-
-
## Constants
@@ -489,6 +457,16 @@ The description is over the maximum length
+
+
+The collection name is invalid
+
+
+const EINVALID_COLLECTION_NAME: u64 = 7;
+
+
+
+
The max supply must be positive
@@ -542,8 +520,7 @@ Beyond that, it adds supply tracking with events.
-
-Implementation
+##### Implementation
public fun create_fixed_collection(
@@ -552,17 +529,16 @@ Beyond that, it adds supply tracking with events.
max_supply: u64,
name: String,
royalty: Option<Royalty>,
- uri: String,
+ uri: String
): ConstructorRef {
- assert!(max_supply != 0, error::invalid_argument(EMAX_SUPPLY_CANNOT_BE_ZERO));
+ assert!(
+ max_supply != 0,
+ error::invalid_argument(EMAX_SUPPLY_CANNOT_BE_ZERO)
+ );
let collection_seed = create_collection_seed(&name);
- let constructor_ref = object::create_named_object(creator, collection_seed, false);
+ let constructor_ref = object::create_named_object(creator, collection_seed);
- let supply = FixedSupply {
- current_supply: 0,
- max_supply,
- total_minted: 0,
- };
+ let supply = FixedSupply { current_supply: 0, max_supply, total_minted: 0 };
create_collection_internal(
creator,
@@ -571,15 +547,13 @@ Beyond that, it adds supply tracking with events.
name,
royalty,
uri,
- option::some(supply),
+ option::some(supply)
)
}
-
-
## Function `create_unlimited_collection`
@@ -593,8 +567,7 @@ the supply of nfts.
-
-Implementation
+##### Implementation
public fun create_unlimited_collection(
@@ -602,15 +575,12 @@ the supply of nfts.
description: String,
name: String,
royalty: Option<Royalty>,
- uri: String,
+ uri: String
): ConstructorRef {
let collection_seed = create_collection_seed(&name);
- let constructor_ref = object::create_named_object(creator, collection_seed, false);
+ let constructor_ref = object::create_named_object(creator, collection_seed);
- let supply = UnlimitedSupply {
- current_supply: 0,
- total_minted: 0,
- };
+ let supply = UnlimitedSupply { current_supply: 0, total_minted: 0 };
create_collection_internal(
creator,
@@ -619,122 +589,13 @@ the supply of nfts.
name,
royalty,
uri,
- option::some(supply),
- )
-}
-
-
-
-
-
-
-
-
-## Function `create_untracked_collection`
-
-Creates an untracked collection, or a collection that supports an arbitrary amount of
-nfts. This is useful for mass airdrops that fully leverage Aptos parallelization.
-TODO: Hide this until we bring back meaningful way to enforce burns
-
-
-fun create_untracked_collection(creator: &signer, description: string::String, name: string::String, royalty: option::Option<royalty::Royalty>, uri: string::String): object::ConstructorRef
-
-
-
-
-
-Implementation
-
-
-fun create_untracked_collection(
- creator: &signer,
- description: String,
- name: String,
- royalty: Option<Royalty>,
- uri: String,
-): ConstructorRef {
- let collection_seed = create_collection_seed(&name);
- let constructor_ref = object::create_named_object(creator, collection_seed, false);
-
- create_collection_internal<FixedSupply>(
- creator,
- constructor_ref,
- description,
- name,
- royalty,
- uri,
- option::none(),
+ option::some(supply)
)
}
-
-
-
-
-## Function `create_collection_internal`
-
-
-
-fun create_collection_internal<Supply: key>(creator: &signer, constructor_ref: object::ConstructorRef, description: string::String, name: string::String, royalty: option::Option<royalty::Royalty>, uri: string::String, supply: option::Option<Supply>): object::ConstructorRef
-
-
-
-
-
-Implementation
-
-
-inline fun create_collection_internal<Supply: key>(
- creator: &signer,
- constructor_ref: ConstructorRef,
- description: String,
- name: String,
- royalty: Option<Royalty>,
- uri: String,
- supply: Option<Supply>,
-): ConstructorRef {
- assert!(string::length(&name) <= MAX_COLLECTION_NAME_LENGTH, error::out_of_range(ECOLLECTION_NAME_TOO_LONG));
- assert!(string::length(&uri) <= MAX_URI_LENGTH, error::out_of_range(EURI_TOO_LONG));
- assert!(string::length(&description) <= MAX_DESCRIPTION_LENGTH, error::out_of_range(EDESCRIPTION_TOO_LONG));
-
- let object_signer = &object::generate_signer(&constructor_ref);
- let creator_addr = signer::address_of(creator);
-
- let collection = Collection {
- creator: creator_addr,
- description,
- name,
- uri,
- nfts: table::new(),
- };
- move_to(object_signer, collection);
-
- if (option::is_some(&supply)) {
- move_to(object_signer, option::destroy_some(supply));
- let collection_addr = signer::address_of(object_signer);
- event::emit(CreateCollectionEvent { collection: collection_addr, creator: creator_addr, name });
- } else {
- option::destroy_none(supply)
- };
-
- if (option::is_some(&royalty)) {
- royalty::init(&constructor_ref, option::extract(&mut royalty))
- };
-
- let transfer_ref = object::generate_transfer_ref(&constructor_ref);
- object::disable_ungated_transfer(&transfer_ref);
-
- constructor_ref
-}
-
-
-
-
-
-
## Function `create_collection_address`
@@ -747,19 +608,16 @@ Generates the collections address based upon the creators address and the collec
-
-Implementation
+##### Implementation
public fun create_collection_address(creator: address, name: &String): address {
- object::create_object_address(creator, create_collection_seed(name))
+ object::create_object_address(&creator, create_collection_seed(name))
}
-
-
## Function `create_collection_seed`
@@ -772,20 +630,20 @@ Named objects are derived from a seed, the collection's seed is its name.
-
-Implementation
+##### Implementation
public fun create_collection_seed(name: &String): vector<u8> {
- assert!(string::length(name) <= MAX_COLLECTION_NAME_LENGTH, error::out_of_range(ECOLLECTION_NAME_TOO_LONG));
+ assert!(
+ string::length(name) <= MAX_COLLECTION_NAME_LENGTH,
+ error::out_of_range(ECOLLECTION_NAME_TOO_LONG)
+ );
*string::bytes(name)
}
-
-
## Function `increment_supply`
@@ -798,16 +656,13 @@ Called by nft on mint to increment supply if there's an appropriate Supply struc
-
-Implementation
+##### Implementation
public(friend) fun increment_supply(
- collection: Object<Collection>,
- token_id: String,
- nft: address,
+ collection: Object<Collection>, token_id: String, nft: address
) acquires Collection, FixedSupply, UnlimitedSupply {
- let collection_addr = object::object_address(collection);
+ let collection_addr = object::object_address(&collection);
let collection = borrow_global_mut<Collection>(collection_addr);
if (exists<FixedSupply>(collection_addr)) {
let supply = borrow_global_mut<FixedSupply>(collection_addr);
@@ -815,28 +670,22 @@ Called by nft on mint to increment supply if there's an appropriate Supply struc
supply.total_minted = supply.total_minted + 1;
assert!(
supply.current_supply <= supply.max_supply,
- error::out_of_range(ECOLLECTION_SUPPLY_EXCEEDED),
+ error::out_of_range(ECOLLECTION_SUPPLY_EXCEEDED)
);
table::add(&mut collection.nfts, token_id, nft);
- event::emit(
- MintEvent { collection: collection_addr, token_id, nft },
- );
+ event::emit(MintEvent { collection: collection_addr, token_id, nft });
} else if (exists<UnlimitedSupply>(collection_addr)) {
let supply = borrow_global_mut<UnlimitedSupply>(collection_addr);
supply.current_supply = supply.current_supply + 1;
supply.total_minted = supply.total_minted + 1;
table::add(&mut collection.nfts, token_id, nft);
- event::emit(
- MintEvent { collection: collection_addr, token_id, nft },
- );
+ event::emit(MintEvent { collection: collection_addr, token_id, nft });
}
}
-
-
## Function `decrement_supply`
@@ -849,39 +698,30 @@ Called by nft on burn to decrement supply if there's an appropriate Supply struc
-
-Implementation
+##### Implementation
public(friend) fun decrement_supply(
- collection: Object<Collection>,
- token_id: String,
- nft: address,
+ collection: Object<Collection>, token_id: String, nft: address
) acquires Collection, FixedSupply, UnlimitedSupply {
- let collection_addr = object::object_address(collection);
+ let collection_addr = object::object_address(&collection);
let collection = borrow_global_mut<Collection>(collection_addr);
if (exists<FixedSupply>(collection_addr)) {
let supply = borrow_global_mut<FixedSupply>(collection_addr);
supply.current_supply = supply.current_supply - 1;
table::remove(&mut collection.nfts, token_id);
- event::emit(
- BurnEvent { collection: collection_addr, token_id, nft },
- );
+ event::emit(BurnEvent { collection: collection_addr, token_id, nft });
} else if (exists<UnlimitedSupply>(collection_addr)) {
let supply = borrow_global_mut<UnlimitedSupply>(collection_addr);
supply.current_supply = supply.current_supply - 1;
table::remove(&mut collection.nfts, token_id);
- event::emit(
- BurnEvent { collection: collection_addr, token_id, nft },
- );
+ event::emit(BurnEvent { collection: collection_addr, token_id, nft });
}
}
-
-
## Function `generate_mutator_ref`
@@ -894,73 +734,17 @@ Creates a MutatorRef, which gates the ability to mutate any fields that support
-
-Implementation
+##### Implementation
public fun generate_mutator_ref(ref: &ConstructorRef): MutatorRef {
let object = object::object_from_constructor_ref<Collection>(ref);
- MutatorRef { self: object::object_address(object) }
-}
-
-
-
-
-
-
-
-
-## Function `check_collection_exists`
-
-
-
-fun check_collection_exists(addr: address)
-
-
-
-
-
-Implementation
-
-
-inline fun check_collection_exists(addr: address) {
- assert!(
- exists<Collection>(addr),
- error::not_found(ECOLLECTION_DOES_NOT_EXIST),
- );
-}
-
-
-
-
-
-
-
-
-## Function `borrow`
-
-
-
-fun borrow<T: key>(collection: object::Object<T>): &collection::Collection
-
-
-
-
-
-Implementation
-
-
-inline fun borrow<T: key>(collection: Object<T>): &Collection {
- let collection_address = object::object_address(collection);
- check_collection_exists(collection_address);
- borrow_global<Collection>(collection_address)
+ MutatorRef { self: object::object_address(&object) }
}
-
-
## Function `count`
@@ -974,12 +758,11 @@ Provides the count of the current selection if supply tracking is used
-
-Implementation
+##### Implementation
public fun count<T: key>(collection: Object<T>): Option<u64> acquires FixedSupply, UnlimitedSupply {
- let collection_address = object::object_address(collection);
+ let collection_address = object::object_address(&collection);
check_collection_exists(collection_address);
if (exists<FixedSupply>(collection_address)) {
@@ -996,8 +779,6 @@ Provides the count of the current selection if supply tracking is used
-
-
## Function `creator`
@@ -1010,8 +791,7 @@ Provides the count of the current selection if supply tracking is used
-
-Implementation
+##### Implementation
public fun creator<T: key>(collection: Object<T>): address acquires Collection {
@@ -1021,8 +801,6 @@ Provides the count of the current selection if supply tracking is used
-
-
## Function `description`
@@ -1035,8 +813,7 @@ Provides the count of the current selection if supply tracking is used
-
-Implementation
+##### Implementation
public fun description<T: key>(collection: Object<T>): String acquires Collection {
@@ -1046,8 +823,6 @@ Provides the count of the current selection if supply tracking is used
-
-
## Function `name`
@@ -1060,8 +835,7 @@ Provides the count of the current selection if supply tracking is used
-
-Implementation
+##### Implementation
public fun name<T: key>(collection: Object<T>): String acquires Collection {
@@ -1071,8 +845,6 @@ Provides the count of the current selection if supply tracking is used
-
-
## Function `uri`
@@ -1085,8 +857,7 @@ Provides the count of the current selection if supply tracking is used
-
-Implementation
+##### Implementation
public fun uri<T: key>(collection: Object<T>): String acquires Collection {
@@ -1096,8 +867,6 @@ Provides the count of the current selection if supply tracking is used
-
-
## Function `nfts`
@@ -1112,14 +881,11 @@ if start_after
is not none, seach nfts in range (start_after, ...]
-
-Implementation
+##### Implementation
public fun nfts<T: key>(
- collection: Object<T>,
- start_after: Option<String>,
- limit: u64,
+ collection: Object<T>, start_after: Option<String>, limit: u64
): vector<NftResponse> acquires Collection {
let collection = borrow(collection);
@@ -1131,20 +897,18 @@ if start_after
is not none, seach nfts in range (start_after, ...]
&collection.nfts,
option::none(),
start_after,
- 2,
+ 2
);
let res: vector<NftResponse> = vector[];
- while (table::prepare<String, address>(&mut nfts_iter) && vector::length(&res) < (limit as u64)) {
- let (token_id, nft) = table::next<String, address>(&mut nfts_iter);
+ while (table::prepare<String, address>(nfts_iter)
+ && vector::length(&res) < (limit as u64)) {
+ let (token_id, nft) = table::next<String, address>(nfts_iter);
vector::push_back(
&mut res,
- NftResponse {
- token_id,
- nft: *nft,
- },
+ NftResponse { token_id, nft: *nft }
);
};
@@ -1154,8 +918,6 @@ if start_after
is not none, seach nfts in range (start_after, ...]
-
-
## Function `decompose_nft_response`
@@ -1167,8 +929,7 @@ if start_after
is not none, seach nfts in range (start_after, ...]
-
-Implementation
+##### Implementation
public fun decompose_nft_response(nft_response: &NftResponse): (String, address) {
@@ -1178,33 +939,6 @@ if start_after
is not none, seach nfts in range (start_after, ...]
-
-
-
-
-## Function `borrow_mut`
-
-
-
-fun borrow_mut(mutator_ref: &collection::MutatorRef): &mut collection::Collection
-
-
-
-
-
-Implementation
-
-
-inline fun borrow_mut(mutator_ref: &MutatorRef): &mut Collection {
- check_collection_exists(mutator_ref.self);
- borrow_global_mut<Collection>(mutator_ref.self)
-}
-
-
-
-
-
-
## Function `set_description`
@@ -1216,12 +950,16 @@ if start_after
is not none, seach nfts in range (start_after, ...]
-
-Implementation
+##### Implementation
-public fun set_description(mutator_ref: &MutatorRef, description: String) acquires Collection {
- assert!(string::length(&description) <= MAX_DESCRIPTION_LENGTH, error::out_of_range(EDESCRIPTION_TOO_LONG));
+public fun set_description(
+ mutator_ref: &MutatorRef, description: String
+) acquires Collection {
+ assert!(
+ string::length(&description) <= MAX_DESCRIPTION_LENGTH,
+ error::out_of_range(EDESCRIPTION_TOO_LONG)
+ );
let collection = borrow_mut(mutator_ref);
event::emit(
MutationEvent {
@@ -1229,7 +967,7 @@ if start_after
is not none, seach nfts in range (start_after, ...]
mutated_field_name: string::utf8(b"description"),
old_value: collection.description,
new_value: description
- },
+ }
);
collection.description = description;
}
@@ -1237,8 +975,6 @@ if start_after
is not none, seach nfts in range (start_after, ...]
-
-
## Function `set_uri`
@@ -1250,12 +986,14 @@ if start_after
is not none, seach nfts in range (start_after, ...]
-
-Implementation
+##### Implementation
public fun set_uri(mutator_ref: &MutatorRef, uri: String) acquires Collection {
- assert!(string::length(&uri) <= MAX_URI_LENGTH, error::out_of_range(EURI_TOO_LONG));
+ assert!(
+ string::length(&uri) <= MAX_URI_LENGTH,
+ error::out_of_range(EURI_TOO_LONG)
+ );
let collection = borrow_mut(mutator_ref);
event::emit(
MutationEvent {
@@ -1263,12 +1001,8 @@ if start_after
is not none, seach nfts in range (start_after, ...]
mutated_field_name: string::utf8(b"uri"),
old_value: collection.uri,
new_value: uri
- },
+ }
);
collection.uri = uri;
}
-
-
-
-
diff --git a/initia_stdlib/doc/comparator.md b/initia_stdlib/doc/comparator.md
index f62a107..59afdc2 100644
--- a/initia_stdlib/doc/comparator.md
+++ b/initia_stdlib/doc/comparator.md
@@ -31,8 +31,7 @@ Provides a framework for comparing two elements
-
-Fields
+##### Fields
@@ -45,8 +44,6 @@ Provides a framework for comparing two elements
-
-
## Constants
@@ -90,8 +87,7 @@ Provides a framework for comparing two elements
-
-Implementation
+##### Implementation
public fun is_equal(result: &Result): bool {
@@ -101,8 +97,6 @@ Provides a framework for comparing two elements
-
-
## Function `is_smaller_than`
@@ -114,8 +108,7 @@ Provides a framework for comparing two elements
-
-Implementation
+##### Implementation
public fun is_smaller_than(result: &Result): bool {
@@ -125,8 +118,6 @@ Provides a framework for comparing two elements
-
-
## Function `is_greater_than`
@@ -138,8 +129,7 @@ Provides a framework for comparing two elements
-
-Implementation
+##### Implementation
public fun is_greater_than(result: &Result): bool {
@@ -149,8 +139,6 @@ Provides a framework for comparing two elements
-
-
## Function `compare`
@@ -162,8 +150,7 @@ Provides a framework for comparing two elements
-
-Implementation
+##### Implementation
public fun compare<T>(left: &T, right: &T): Result {
@@ -176,8 +163,6 @@ Provides a framework for comparing two elements
-
-
## Function `compare_u8_vector`
@@ -189,8 +174,7 @@ Provides a framework for comparing two elements
-
-Implementation
+##### Implementation
public fun compare_u8_vector(left: vector<u8>, right: vector<u8>): Result {
@@ -220,7 +204,3 @@ Provides a framework for comparing two elements
}
}
-
-
-
-
diff --git a/initia_stdlib/doc/copyable_any.md b/initia_stdlib/doc/copyable_any.md
index 36ce028..ae04079 100644
--- a/initia_stdlib/doc/copyable_any.md
+++ b/initia_stdlib/doc/copyable_any.md
@@ -33,8 +33,7 @@ The same as any::Any
but with the
-
-Fields
+##### Fields
@@ -53,8 +52,6 @@ The same as any::Any
but with the
-
-
## Constants
@@ -83,8 +80,7 @@ also required from T
.
-
-Implementation
+##### Implementation
public fun pack<T: drop + store + copy>(x: T): Any {
@@ -97,8 +93,6 @@ also required from T
.
-
-
## Function `unpack`
@@ -111,20 +105,20 @@ Unpack a value from the Any
-
-Implementation
+##### Implementation
public fun unpack<T>(x: Any): T {
- assert!(type_info::type_name<T>() == x.type_name, error::invalid_argument(ETYPE_MISMATCH));
+ assert!(
+ type_info::type_name<T>() == x.type_name,
+ error::invalid_argument(ETYPE_MISMATCH)
+ );
from_bytes<T>(x.data)
}
-
-
## Function `type_name`
@@ -137,15 +131,10 @@ Returns the type name of this Any
-
-Implementation
+##### Implementation
public fun type_name(x: &Any): &String {
&x.type_name
}
-
-
-
-
diff --git a/initia_stdlib/doc/cosmos.md b/initia_stdlib/doc/cosmos.md
index 87cd5ea..689c9ba 100644
--- a/initia_stdlib/doc/cosmos.md
+++ b/initia_stdlib/doc/cosmos.md
@@ -7,6 +7,7 @@ This module provides interfaces to allow CosmosMessage
execution after the move execution finished.
+- [Struct `VoteRequest`](#0x1_cosmos_VoteRequest)
- [Function `stargate_vote`](#0x1_cosmos_stargate_vote)
- [Function `stargate`](#0x1_cosmos_stargate)
- [Function `move_execute`](#0x1_cosmos_move_execute)
@@ -18,28 +19,66 @@ execution after the move execution finished.
- [Function `transfer`](#0x1_cosmos_transfer)
- [Function `nft_transfer`](#0x1_cosmos_nft_transfer)
- [Function `pay_fee`](#0x1_cosmos_pay_fee)
-- [Function `stargate_internal`](#0x1_cosmos_stargate_internal)
-- [Function `move_execute_internal`](#0x1_cosmos_move_execute_internal)
-- [Function `move_script_internal`](#0x1_cosmos_move_script_internal)
-- [Function `delegate_internal`](#0x1_cosmos_delegate_internal)
-- [Function `fund_community_pool_internal`](#0x1_cosmos_fund_community_pool_internal)
-- [Function `transfer_internal`](#0x1_cosmos_transfer_internal)
-- [Function `nft_transfer_internal`](#0x1_cosmos_nft_transfer_internal)
-- [Function `pay_fee_internal`](#0x1_cosmos_pay_fee_internal)
use 0x1::collection;
use 0x1::fungible_asset;
use 0x1::json;
use 0x1::object;
-use 0x1::option;
use 0x1::signer;
-use 0x1::simple_json;
use 0x1::string;
+
+
+## Struct `VoteRequest`
+
+
+
+struct VoteRequest has copy, drop
+
+
+
+
+##### Fields
+
+
+
+-
+
_type_: string::String
+
+-
+
+
+-
+
proposal_id: u64
+
+-
+
+
+-
+
voter: string::String
+
+-
+
+
+-
+
option: u64
+
+-
+
+
+-
+
metadata: string::String
+
+-
+
+
+
+
+
## Function `stargate_vote`
@@ -51,8 +90,7 @@ execution after the move execution finished.
-
-Implementation
+##### Implementation
public entry fun stargate_vote(
@@ -62,54 +100,44 @@ execution after the move execution finished.
option: u64,
metadata: String
) {
- let obj = simple_json::empty();
- simple_json::set_object(&mut obj, option::none<String>());
- simple_json::increase_depth(&mut obj);
- simple_json::set_int_raw(&mut obj, option::some(string::utf8(b"proposal_id")), true, (proposal_id as u256));
- simple_json::set_string(&mut obj, option::some(string::utf8(b"voter")), voter);
- simple_json::set_int_raw(&mut obj, option::some(string::utf8(b"option")), true, (option as u256));
- simple_json::set_string(&mut obj, option::some(string::utf8(b"metadata")), metadata);
- simple_json::set_string(&mut obj, option::some(string::utf8(b"@type")), string::utf8(b"/cosmos.gov.v1.MsgVote"));
-
- let req = json::stringify(simple_json::to_json_object(&obj));
- stargate(sender, req);
+ stargate(
+ sender,
+ json::marshal(
+ &VoteRequest {
+ _type_: string::utf8(b"/cosmos.gov.v1.MsgVote"),
+ proposal_id,
+ voter,
+ option,
+ metadata
+ }
+ )
+ );
}
-
-
## Function `stargate`
-public entry fun stargate(sender: &signer, data: string::String)
+public entry fun stargate(sender: &signer, data: vector<u8>)
-
-Implementation
+##### Implementation
-public entry fun stargate (
- sender: &signer,
- data: String,
-) {
- stargate_internal(
- signer::address_of(sender),
- *string::bytes(&data),
- )
+public entry fun stargate(sender: &signer, data: vector<u8>) {
+ stargate_internal(signer::address_of(sender), data)
}
-
-
## Function `move_execute`
@@ -121,17 +149,16 @@ execution after the move execution finished.
-
-Implementation
+##### Implementation
-public entry fun move_execute (
+public entry fun move_execute(
sender: &signer,
module_address: address,
module_name: String,
function_name: String,
type_args: vector<String>,
- args: vector<vector<u8>>,
+ args: vector<vector<u8>>
) {
move_execute_internal(
signer::address_of(sender),
@@ -140,15 +167,13 @@ execution after the move execution finished.
*string::bytes(&function_name),
vector::map_ref(&type_args, |v| *string::bytes(v)),
args,
- false,
+ false
)
}
-
-
## Function `move_execute_with_json`
@@ -160,17 +185,16 @@ execution after the move execution finished.
-
-Implementation
+##### Implementation
-public entry fun move_execute_with_json (
+public entry fun move_execute_with_json(
sender: &signer,
module_address: address,
module_name: String,
function_name: String,
type_args: vector<String>,
- args: vector<String>,
+ args: vector<String>
) {
move_execute_internal(
signer::address_of(sender),
@@ -179,15 +203,13 @@ execution after the move execution finished.
*string::bytes(&function_name),
vector::map_ref(&type_args, |v| *string::bytes(v)),
vector::map_ref(&args, |v| *string::bytes(v)),
- true,
+ true
)
}
-
-
## Function `move_script`
@@ -199,30 +221,27 @@ execution after the move execution finished.
-
-Implementation
+##### Implementation
-public entry fun move_script (
+public entry fun move_script(
sender: &signer,
code_bytes: vector<u8>,
type_args: vector<String>,
- args: vector<vector<u8>>,
+ args: vector<vector<u8>>
) {
move_script_internal(
signer::address_of(sender),
code_bytes,
vector::map_ref(&type_args, |v| *string::bytes(v)),
args,
- false,
+ false
)
}
-
-
## Function `move_script_with_json`
@@ -234,30 +253,27 @@ execution after the move execution finished.
-
-Implementation
+##### Implementation
-public entry fun move_script_with_json (
+public entry fun move_script_with_json(
sender: &signer,
code_bytes: vector<u8>,
type_args: vector<String>,
- args: vector<String>,
+ args: vector<String>
) {
move_script_internal(
signer::address_of(sender),
code_bytes,
vector::map_ref(&type_args, |v| *string::bytes(v)),
vector::map_ref(&args, |v| *string::bytes(v)),
- true,
+ true
)
}
-
-
## Function `delegate`
@@ -269,29 +285,26 @@ execution after the move execution finished.
-
-Implementation
+##### Implementation
-public entry fun delegate (
+public entry fun delegate(
delegator: &signer,
validator: String,
metadata: Object<Metadata>,
- amount: u64,
+ amount: u64
) {
delegate_internal(
signer::address_of(delegator),
*string::bytes(&validator),
&metadata,
- amount,
+ amount
)
}
-
-
## Function `fund_community_pool`
@@ -303,27 +316,22 @@ execution after the move execution finished.
-
-Implementation
+##### Implementation
-public entry fun fund_community_pool (
- sender: &signer,
- metadata: Object<Metadata>,
- amount: u64,
+public entry fun fund_community_pool(
+ sender: &signer, metadata: Object<Metadata>, amount: u64
) {
fund_community_pool_internal(
signer::address_of(sender),
&metadata,
- amount,
+ amount
)
}
-
-
## Function `transfer`
@@ -337,11 +345,10 @@ https://github.com/cosmos/ibc/tree/main/spec/app/ics-020-fungible-token-transfer
-
-Implementation
+##### Implementation
-public entry fun transfer (
+public entry fun transfer(
sender: &signer,
receiver: String,
metadata: Object<Metadata>,
@@ -351,7 +358,7 @@ https://github.com/cosmos/ibc/tree/main/spec/app/ics-020-fungible-token-transfer
revision_number: u64,
revision_height: u64,
timeout_timestamp: u64,
- memo: String,
+ memo: String
) {
transfer_internal(
signer::address_of(sender),
@@ -363,15 +370,13 @@ https://github.com/cosmos/ibc/tree/main/spec/app/ics-020-fungible-token-transfer
revision_number,
revision_height,
timeout_timestamp,
- *string::bytes(&memo),
+ *string::bytes(&memo)
)
}
-
-
## Function `nft_transfer`
@@ -385,11 +390,10 @@ https://github.com/cosmos/ibc/tree/main/spec/app/ics-721-nft-transfer
-
-Implementation
+##### Implementation
-public entry fun nft_transfer (
+public entry fun nft_transfer(
sender: &signer,
receiver: String,
collection: Object<Collection>,
@@ -399,7 +403,7 @@ https://github.com/cosmos/ibc/tree/main/spec/app/ics-721-nft-transfer
revision_number: u64,
revision_height: u64,
timeout_timestamp: u64,
- memo: String,
+ memo: String
) {
nft_transfer_internal(
signer::address_of(sender),
@@ -411,15 +415,13 @@ https://github.com/cosmos/ibc/tree/main/spec/app/ics-721-nft-transfer
revision_number,
revision_height,
timeout_timestamp,
- *string::bytes(&memo),
+ *string::bytes(&memo)
)
}
-
-
## Function `pay_fee`
@@ -433,11 +435,10 @@ https://github.com/cosmos/ibc/tree/main/spec/app/ics-029-fee-payment
-
-Implementation
+##### Implementation
-public entry fun pay_fee (
+public entry fun pay_fee(
sender: &signer,
source_port: String,
source_channel: String,
@@ -446,7 +447,7 @@ https://github.com/cosmos/ibc/tree/main/spec/app/ics-029-fee-payment
ack_fee_metadata: Object<Metadata>,
ack_fee_amount: u64,
timeout_fee_metadata: Object<Metadata>,
- timeout_fee_amount: u64,
+ timeout_fee_amount: u64
) {
pay_fee_internal(
signer::address_of(sender),
@@ -457,245 +458,7 @@ https://github.com/cosmos/ibc/tree/main/spec/app/ics-029-fee-payment
&ack_fee_metadata,
ack_fee_amount,
&timeout_fee_metadata,
- timeout_fee_amount,
+ timeout_fee_amount
)
}
-
-
-
-
-
-
-
-## Function `stargate_internal`
-
-
-
-fun stargate_internal(sender: address, data: vector<u8>)
-
-
-
-
-
-Implementation
-
-
-native fun stargate_internal (
- sender: address,
- data: vector<u8>,
-);
-
-
-
-
-
-
-
-
-## Function `move_execute_internal`
-
-
-
-fun move_execute_internal(sender: address, module_address: address, module_name: vector<u8>, function_name: vector<u8>, type_args: vector<vector<u8>>, args: vector<vector<u8>>, is_json: bool)
-
-
-
-
-
-Implementation
-
-
-native fun move_execute_internal (
- sender: address,
- module_address: address,
- module_name: vector<u8>,
- function_name: vector<u8>,
- type_args: vector<vector<u8>>,
- args: vector<vector<u8>>,
- is_json: bool,
-);
-
-
-
-
-
-
-
-
-## Function `move_script_internal`
-
-
-
-fun move_script_internal(sender: address, code_bytes: vector<u8>, type_args: vector<vector<u8>>, args: vector<vector<u8>>, is_json: bool)
-
-
-
-
-
-Implementation
-
-
-native fun move_script_internal (
- sender: address,
- code_bytes: vector<u8>,
- type_args: vector<vector<u8>>,
- args: vector<vector<u8>>,
- is_json: bool,
-);
-
-
-
-
-
-
-
-
-## Function `delegate_internal`
-
-
-
-fun delegate_internal(delegator: address, validator: vector<u8>, metadata: &object::Object<fungible_asset::Metadata>, amount: u64)
-
-
-
-
-
-Implementation
-
-
-native fun delegate_internal (
- delegator: address,
- validator: vector<u8>,
- metadata: &Object<Metadata>,
- amount: u64,
-);
-
-
-
-
-
-
-
-
-## Function `fund_community_pool_internal`
-
-
-
-fun fund_community_pool_internal(sender: address, metadata: &object::Object<fungible_asset::Metadata>, amount: u64)
-
-
-
-
-
-Implementation
-
-
-native fun fund_community_pool_internal (
- sender: address,
- metadata: &Object<Metadata>,
- amount: u64,
-);
-
-
-
-
-
-
-
-
-## Function `transfer_internal`
-
-
-
-fun transfer_internal(sender: address, receiver: vector<u8>, metadata: &object::Object<fungible_asset::Metadata>, token_amount: u64, source_port: vector<u8>, source_channel: vector<u8>, revision_number: u64, revision_height: u64, timeout_timestamp: u64, memo: vector<u8>)
-
-
-
-
-
-Implementation
-
-
-native fun transfer_internal (
- sender: address,
- receiver: vector<u8>,
- metadata: &Object<Metadata>,
- token_amount: u64,
- source_port: vector<u8>,
- source_channel: vector<u8>,
- revision_number: u64,
- revision_height: u64,
- timeout_timestamp: u64,
- memo: vector<u8>,
-);
-
-
-
-
-
-
-
-
-## Function `nft_transfer_internal`
-
-
-
-fun nft_transfer_internal(sender: address, receiver: vector<u8>, collection: &object::Object<collection::Collection>, token_ids: vector<vector<u8>>, source_port: vector<u8>, source_channel: vector<u8>, revision_number: u64, revision_height: u64, timeout_timestamp: u64, memo: vector<u8>)
-
-
-
-
-
-Implementation
-
-
-native fun nft_transfer_internal (
- sender: address,
- receiver: vector<u8>,
- collection: &Object<Collection>,
- token_ids: vector<vector<u8>>,
- source_port: vector<u8>,
- source_channel: vector<u8>,
- revision_number: u64,
- revision_height: u64,
- timeout_timestamp: u64,
- memo: vector<u8>,
-);
-
-
-
-
-
-
-
-
-## Function `pay_fee_internal`
-
-
-
-fun pay_fee_internal(sender: address, source_port: vector<u8>, source_channel: vector<u8>, recv_fee_metadata: &object::Object<fungible_asset::Metadata>, recv_fee_amount: u64, ack_fee_metadata: &object::Object<fungible_asset::Metadata>, ack_fee_amount: u64, timeout_fee_metadata: &object::Object<fungible_asset::Metadata>, timeout_fee_amount: u64)
-
-
-
-
-
-Implementation
-
-
-native fun pay_fee_internal (
- sender: address,
- source_port: vector<u8>,
- source_channel: vector<u8>,
- recv_fee_metadata: &Object<Metadata>,
- recv_fee_amount: u64,
- ack_fee_metadata: &Object<Metadata>,
- ack_fee_amount: u64,
- timeout_fee_metadata: &Object<Metadata>,
- timeout_fee_amount: u64,
-);
-
-
-
-
-
diff --git a/initia_stdlib/doc/debug.md b/initia_stdlib/doc/debug.md
index 029ff17..9be477b 100644
--- a/initia_stdlib/doc/debug.md
+++ b/initia_stdlib/doc/debug.md
@@ -9,9 +9,6 @@ Module providing debug functionality.
- [Constants](#@Constants_0)
- [Function `print`](#0x1_debug_print)
- [Function `print_stack_trace`](#0x1_debug_print_stack_trace)
-- [Function `format`](#0x1_debug_format)
-- [Function `native_print`](#0x1_debug_native_print)
-- [Function `native_stack_trace`](#0x1_debug_native_stack_trace)
use 0x1::string;
@@ -54,8 +51,7 @@ Module providing debug functionality.
-
-Implementation
+##### Implementation
public fun print<T>(x: &T) {
@@ -65,8 +61,6 @@ Module providing debug functionality.
-
-
## Function `print_stack_trace`
@@ -78,83 +72,10 @@ Module providing debug functionality.
-
-Implementation
+##### Implementation
public fun print_stack_trace() {
native_print(native_stack_trace());
}
-
-
-
-
-
-
-
-## Function `format`
-
-
-
-fun format<T>(x: &T): string::String
-
-
-
-
-
-Implementation
-
-
-inline fun format<T>(x: &T): String {
- debug_string(x)
-}
-
-
-
-
-
-
-
-
-## Function `native_print`
-
-
-
-fun native_print(x: string::String)
-
-
-
-
-
-Implementation
-
-
-native fun native_print(x: String);
-
-
-
-
-
-
-
-
-## Function `native_stack_trace`
-
-
-
-fun native_stack_trace(): string::String
-
-
-
-
-
-Implementation
-
-
-native fun native_stack_trace(): String;
-
-
-
-
-
diff --git a/initia_stdlib/doc/decimal128.md b/initia_stdlib/doc/decimal128.md
deleted file mode 100644
index 2d20494..0000000
--- a/initia_stdlib/doc/decimal128.md
+++ /dev/null
@@ -1,579 +0,0 @@
-
-
-
-# Module `0x1::decimal128`
-
-
-
-- [Struct `Decimal128`](#0x1_decimal128_Decimal128)
-- [Constants](#@Constants_0)
-- [Function `new`](#0x1_decimal128_new)
-- [Function `new_u64`](#0x1_decimal128_new_u64)
-- [Function `one`](#0x1_decimal128_one)
-- [Function `zero`](#0x1_decimal128_zero)
-- [Function `from_ratio_u64`](#0x1_decimal128_from_ratio_u64)
-- [Function `from_ratio`](#0x1_decimal128_from_ratio)
-- [Function `add`](#0x1_decimal128_add)
-- [Function `sub`](#0x1_decimal128_sub)
-- [Function `mul_u64`](#0x1_decimal128_mul_u64)
-- [Function `mul_u128`](#0x1_decimal128_mul_u128)
-- [Function `mul`](#0x1_decimal128_mul)
-- [Function `div_u64`](#0x1_decimal128_div_u64)
-- [Function `div`](#0x1_decimal128_div)
-- [Function `val`](#0x1_decimal128_val)
-- [Function `is_same`](#0x1_decimal128_is_same)
-- [Function `from_string`](#0x1_decimal128_from_string)
-- [Function `pow`](#0x1_decimal128_pow)
-
-
-use 0x1::error;
-use 0x1::string;
-
-
-
-
-
-
-## Struct `Decimal128`
-
-A fixed-point decimal value with 18 fractional digits, i.e. Decimal128{ val: 1_000_000_000_000_000_000 } == 1.0
-
-
-struct Decimal128 has copy, drop, store
-
-
-
-
-
-Fields
-
-
-
--
-
val: u128
-
--
-
-
-
-
-
-
-
-
-
-## Constants
-
-
-
-
-
-
-const DECIMAL_FRACTIONAL: u128 = 1000000000000000000;
-
-
-
-
-
-
-
-
-const EDIV_WITH_ZERO: u64 = 0;
-
-
-
-
-
-
-
-
-const EFAILED_TO_DESERIALIZE: u64 = 1;
-
-
-
-
-
-
-
-
-const EOUT_OF_RANGE: u64 = 2;
-
-
-
-
-
-
-
-
-const FRACTIONAL_LENGTH: u64 = 18;
-
-
-
-
-
-
-
-
-const MAX_INTEGER_PART: u128 = 340282366920938463463;
-
-
-
-
-
-
-## Function `new`
-
-
-
-public fun new(val: u128): decimal128::Decimal128
-
-
-
-
-
-Implementation
-
-
-public fun new(val: u128): Decimal128 {
- Decimal128 { val }
-}
-
-
-
-
-
-
-
-
-## Function `new_u64`
-
-
-
-public fun new_u64(val: u64): decimal128::Decimal128
-
-
-
-
-
-Implementation
-
-
-public fun new_u64(val: u64): Decimal128 {
- Decimal128 { val: (val as u128) }
-}
-
-
-
-
-
-
-
-
-## Function `one`
-
-
-
-public fun one(): decimal128::Decimal128
-
-
-
-
-
-Implementation
-
-
-public fun one(): Decimal128 {
- Decimal128 { val: DECIMAL_FRACTIONAL }
-}
-
-
-
-
-
-
-
-
-## Function `zero`
-
-
-
-public fun zero(): decimal128::Decimal128
-
-
-
-
-
-Implementation
-
-
-public fun zero(): Decimal128 {
- Decimal128 { val: 0 }
-}
-
-
-
-
-
-
-
-
-## Function `from_ratio_u64`
-
-
-
-public fun from_ratio_u64(numerator: u64, denominator: u64): decimal128::Decimal128
-
-
-
-
-
-Implementation
-
-
-public fun from_ratio_u64(numerator: u64, denominator: u64): Decimal128 {
- assert!(denominator != 0, EDIV_WITH_ZERO);
-
- new((numerator as u128) * DECIMAL_FRACTIONAL / (denominator as u128))
-}
-
-
-
-
-
-
-
-
-## Function `from_ratio`
-
-
-
-public fun from_ratio(numerator: u128, denominator: u128): decimal128::Decimal128
-
-
-
-
-
-Implementation
-
-
-public fun from_ratio(numerator: u128, denominator: u128): Decimal128 {
- assert!(denominator != 0, EDIV_WITH_ZERO);
-
- new(numerator * DECIMAL_FRACTIONAL / denominator)
-}
-
-
-
-
-
-
-
-
-## Function `add`
-
-
-
-public fun add(left: &decimal128::Decimal128, right: &decimal128::Decimal128): decimal128::Decimal128
-
-
-
-
-
-Implementation
-
-
-public fun add(left: &Decimal128, right: &Decimal128): Decimal128 {
- new(left.val + right.val)
-}
-
-
-
-
-
-
-
-
-## Function `sub`
-
-
-
-public fun sub(left: &decimal128::Decimal128, right: &decimal128::Decimal128): decimal128::Decimal128
-
-
-
-
-
-Implementation
-
-
-public fun sub(left: &Decimal128, right: &Decimal128): Decimal128 {
- new(left.val - right.val)
-}
-
-
-
-
-
-
-
-
-## Function `mul_u64`
-
-
-
-public fun mul_u64(decimal: &decimal128::Decimal128, val: u64): u64
-
-
-
-
-
-Implementation
-
-
-public fun mul_u64(decimal: &Decimal128, val: u64): u64 {
- (decimal.val * (val as u128) / DECIMAL_FRACTIONAL as u64)
-}
-
-
-
-
-
-
-
-
-## Function `mul_u128`
-
-
-
-public fun mul_u128(decimal: &decimal128::Decimal128, val: u128): u128
-
-
-
-
-
-Implementation
-
-
-public fun mul_u128(decimal: &Decimal128, val: u128): u128 {
- decimal.val * val / DECIMAL_FRACTIONAL
-}
-
-
-
-
-
-
-
-
-## Function `mul`
-
-
-
-public fun mul(a: &decimal128::Decimal128, b: &decimal128::Decimal128): decimal128::Decimal128
-
-
-
-
-
-Implementation
-
-
-public fun mul(a: &Decimal128, b: &Decimal128): Decimal128 {
- new(a.val * b.val / DECIMAL_FRACTIONAL)
-}
-
-
-
-
-
-
-
-
-## Function `div_u64`
-
-
-
-public fun div_u64(decimal: &decimal128::Decimal128, val: u64): decimal128::Decimal128
-
-
-
-
-
-Implementation
-
-
-public fun div_u64(decimal: &Decimal128, val: u64): Decimal128 {
- new(decimal.val / (val as u128))
-}
-
-
-
-
-
-
-
-
-## Function `div`
-
-
-
-public fun div(decimal: &decimal128::Decimal128, val: u128): decimal128::Decimal128
-
-
-
-
-
-Implementation
-
-
-public fun div(decimal: &Decimal128, val: u128): Decimal128 {
- new(decimal.val / val)
-}
-
-
-
-
-
-
-
-
-## Function `val`
-
-
-
-public fun val(decimal: &decimal128::Decimal128): u128
-
-
-
-
-
-Implementation
-
-
-public fun val(decimal: &Decimal128): u128 {
- decimal.val
-}
-
-
-
-
-
-
-
-
-## Function `is_same`
-
-
-
-public fun is_same(left: &decimal128::Decimal128, right: &decimal128::Decimal128): bool
-
-
-
-
-
-Implementation
-
-
-public fun is_same(left: &Decimal128, right: &Decimal128): bool {
- left.val == right.val
-}
-
-
-
-
-
-
-
-
-## Function `from_string`
-
-
-
-public fun from_string(num: &string::String): decimal128::Decimal128
-
-
-
-
-
-Implementation
-
-
-public fun from_string(num: &String): Decimal128 {
- let vec = string::bytes(num);
- let len = vector::length(vec);
-
- let cursor = 0;
- let dot_index = 0;
- let val: u128 = 0;
- while (cursor < len) {
- let s = *vector::borrow(vec, cursor);
- cursor = cursor + 1;
-
- // find `.` position
- if (s == 46) continue;
-
- val = val * 10;
- assert!(s >= 48 && s <= 57, error::invalid_argument(EFAILED_TO_DESERIALIZE));
-
- let n = (s - 48 as u128);
- val = val + n;
-
- if (cursor == dot_index + 1) {
- // use `<` not `<=` to safely check "out of range"
- // (i.e. to avoid fractional part checking)
- assert!(val < MAX_INTEGER_PART, error::invalid_argument(EOUT_OF_RANGE));
-
- dot_index = dot_index + 1;
- };
- };
-
- // ignore fractional part longer than `FRACTIONAL_LENGTH`
- let val = if (dot_index == len) {
- val * pow(10, FRACTIONAL_LENGTH)
- } else {
- let fractional_length = len - dot_index - 1;
- if (fractional_length > FRACTIONAL_LENGTH) {
- val / pow(10, fractional_length - FRACTIONAL_LENGTH)
- } else {
- val * pow(10, FRACTIONAL_LENGTH - fractional_length)
- }
- };
-
- new(val)
-}
-
-
-
-
-
-
-
-
-## Function `pow`
-
-
-
-fun pow(num: u128, pow_amount: u64): u128
-
-
-
-
-
-Implementation
-
-
-fun pow(num: u128, pow_amount: u64): u128 {
- let index = 0;
- let val = 1;
- while (index < pow_amount) {
- val = val * num;
- index = index + 1;
- };
-
- val
-}
-
-
-
-
-
diff --git a/initia_stdlib/doc/decimal256.md b/initia_stdlib/doc/decimal256.md
deleted file mode 100644
index bb0add4..0000000
--- a/initia_stdlib/doc/decimal256.md
+++ /dev/null
@@ -1,681 +0,0 @@
-
-
-
-# Module `0x1::decimal256`
-
-
-
-- [Struct `Decimal256`](#0x1_decimal256_Decimal256)
-- [Constants](#@Constants_0)
-- [Function `new`](#0x1_decimal256_new)
-- [Function `new_u64`](#0x1_decimal256_new_u64)
-- [Function `new_u128`](#0x1_decimal256_new_u128)
-- [Function `one`](#0x1_decimal256_one)
-- [Function `zero`](#0x1_decimal256_zero)
-- [Function `from_ratio_u64`](#0x1_decimal256_from_ratio_u64)
-- [Function `from_ratio_u128`](#0x1_decimal256_from_ratio_u128)
-- [Function `from_ratio`](#0x1_decimal256_from_ratio)
-- [Function `add`](#0x1_decimal256_add)
-- [Function `sub`](#0x1_decimal256_sub)
-- [Function `mul_u64`](#0x1_decimal256_mul_u64)
-- [Function `mul_u128`](#0x1_decimal256_mul_u128)
-- [Function `mul_u256`](#0x1_decimal256_mul_u256)
-- [Function `mul`](#0x1_decimal256_mul)
-- [Function `div_u64`](#0x1_decimal256_div_u64)
-- [Function `div_u128`](#0x1_decimal256_div_u128)
-- [Function `div`](#0x1_decimal256_div)
-- [Function `val`](#0x1_decimal256_val)
-- [Function `is_same`](#0x1_decimal256_is_same)
-- [Function `from_string`](#0x1_decimal256_from_string)
-- [Function `pow`](#0x1_decimal256_pow)
-
-
-use 0x1::error;
-use 0x1::string;
-
-
-
-
-
-
-## Struct `Decimal256`
-
-A fixed-point decimal value with 18 fractional digits, i.e. Decimal256{ val: 1_000_000_000_000_000_000 } == 1.0
-
-
-struct Decimal256 has copy, drop, store
-
-
-
-
-
-Fields
-
-
-
--
-
val: u256
-
--
-
-
-
-
-
-
-
-
-
-## Constants
-
-
-
-
-
-
-const DECIMAL_FRACTIONAL: u256 = 1000000000000000000;
-
-
-
-
-
-
-
-
-const EDIV_WITH_ZERO: u64 = 0;
-
-
-
-
-
-
-
-
-const EFAILED_TO_DESERIALIZE: u64 = 1;
-
-
-
-
-
-
-
-
-const EOUT_OF_RANGE: u64 = 2;
-
-
-
-
-
-
-
-
-const FRACTIONAL_LENGTH: u64 = 18;
-
-
-
-
-
-
-
-
-const MAX_INTEGER_PART: u256 = 115792089237316195423570985008687907853269984665640564039457;
-
-
-
-
-
-
-## Function `new`
-
-
-
-public fun new(val: u256): decimal256::Decimal256
-
-
-
-
-
-Implementation
-
-
-public fun new(val: u256): Decimal256 {
- Decimal256 { val }
-}
-
-
-
-
-
-
-
-
-## Function `new_u64`
-
-
-
-public fun new_u64(val: u64): decimal256::Decimal256
-
-
-
-
-
-Implementation
-
-
-public fun new_u64(val: u64): Decimal256 {
- Decimal256 { val: (val as u256) }
-}
-
-
-
-
-
-
-
-
-## Function `new_u128`
-
-
-
-public fun new_u128(val: u128): decimal256::Decimal256
-
-
-
-
-
-Implementation
-
-
-public fun new_u128(val: u128): Decimal256 {
- Decimal256 { val: (val as u256) }
-}
-
-
-
-
-
-
-
-
-## Function `one`
-
-
-
-public fun one(): decimal256::Decimal256
-
-
-
-
-
-Implementation
-
-
-public fun one(): Decimal256 {
- Decimal256 { val: DECIMAL_FRACTIONAL }
-}
-
-
-
-
-
-
-
-
-## Function `zero`
-
-
-
-public fun zero(): decimal256::Decimal256
-
-
-
-
-
-Implementation
-
-
-public fun zero(): Decimal256 {
- Decimal256 { val: 0 }
-}
-
-
-
-
-
-
-
-
-## Function `from_ratio_u64`
-
-
-
-public fun from_ratio_u64(numerator: u64, denominator: u64): decimal256::Decimal256
-
-
-
-
-
-Implementation
-
-
-public fun from_ratio_u64(numerator: u64, denominator: u64): Decimal256 {
- assert!(denominator != 0, EDIV_WITH_ZERO);
-
- new((numerator as u256) * DECIMAL_FRACTIONAL / (denominator as u256))
-}
-
-
-
-
-
-
-
-
-## Function `from_ratio_u128`
-
-
-
-public fun from_ratio_u128(numerator: u128, denominator: u128): decimal256::Decimal256
-
-
-
-
-
-Implementation
-
-
-public fun from_ratio_u128(numerator: u128, denominator: u128): Decimal256 {
- assert!(denominator != 0, EDIV_WITH_ZERO);
-
- new((numerator as u256) * DECIMAL_FRACTIONAL / (denominator as u256))
-}
-
-
-
-
-
-
-
-
-## Function `from_ratio`
-
-
-
-public fun from_ratio(numerator: u256, denominator: u256): decimal256::Decimal256
-
-
-
-
-
-Implementation
-
-
-public fun from_ratio(numerator: u256, denominator: u256): Decimal256 {
- assert!(denominator != 0, EDIV_WITH_ZERO);
-
- new(numerator * DECIMAL_FRACTIONAL / denominator)
-}
-
-
-
-
-
-
-
-
-## Function `add`
-
-
-
-public fun add(left: &decimal256::Decimal256, right: &decimal256::Decimal256): decimal256::Decimal256
-
-
-
-
-
-Implementation
-
-
-public fun add(left: &Decimal256, right: &Decimal256): Decimal256 {
- new(left.val + right.val)
-}
-
-
-
-
-
-
-
-
-## Function `sub`
-
-
-
-public fun sub(left: &decimal256::Decimal256, right: &decimal256::Decimal256): decimal256::Decimal256
-
-
-
-
-
-Implementation
-
-
-public fun sub(left: &Decimal256, right: &Decimal256): Decimal256 {
- new(left.val - right.val)
-}
-
-
-
-
-
-
-
-
-## Function `mul_u64`
-
-
-
-public fun mul_u64(decimal: &decimal256::Decimal256, val: u64): u64
-
-
-
-
-
-Implementation
-
-
-public fun mul_u64(decimal: &Decimal256, val: u64): u64 {
- (decimal.val * (val as u256) / DECIMAL_FRACTIONAL as u64)
-}
-
-
-
-
-
-
-
-
-## Function `mul_u128`
-
-
-
-public fun mul_u128(decimal: &decimal256::Decimal256, val: u128): u128
-
-
-
-
-
-Implementation
-
-
-public fun mul_u128(decimal: &Decimal256, val: u128): u128 {
- (decimal.val * (val as u256) / DECIMAL_FRACTIONAL as u128)
-}
-
-
-
-
-
-
-
-
-## Function `mul_u256`
-
-
-
-public fun mul_u256(decimal: &decimal256::Decimal256, val: u256): u256
-
-
-
-
-
-Implementation
-
-
-public fun mul_u256(decimal: &Decimal256, val: u256): u256 {
- decimal.val * val / DECIMAL_FRACTIONAL
-}
-
-
-
-
-
-
-
-
-## Function `mul`
-
-
-
-public fun mul(a: &decimal256::Decimal256, b: &decimal256::Decimal256): decimal256::Decimal256
-
-
-
-
-
-Implementation
-
-
-public fun mul(a: &Decimal256, b: &Decimal256): Decimal256 {
- new(a.val * b.val / DECIMAL_FRACTIONAL)
-}
-
-
-
-
-
-
-
-
-## Function `div_u64`
-
-
-
-public fun div_u64(decimal: &decimal256::Decimal256, val: u64): decimal256::Decimal256
-
-
-
-
-
-Implementation
-
-
-public fun div_u64(decimal: &Decimal256, val: u64): Decimal256 {
- new(decimal.val / (val as u256))
-}
-
-
-
-
-
-
-
-
-## Function `div_u128`
-
-
-
-public fun div_u128(decimal: &decimal256::Decimal256, val: u128): decimal256::Decimal256
-
-
-
-
-
-Implementation
-
-
-public fun div_u128(decimal: &Decimal256, val: u128): Decimal256 {
- new(decimal.val / (val as u256))
-}
-
-
-
-
-
-
-
-
-## Function `div`
-
-
-
-public fun div(decimal: &decimal256::Decimal256, val: u256): decimal256::Decimal256
-
-
-
-
-
-Implementation
-
-
-public fun div(decimal: &Decimal256, val: u256): Decimal256 {
- new(decimal.val / val)
-}
-
-
-
-
-
-
-
-
-## Function `val`
-
-
-
-public fun val(decimal: &decimal256::Decimal256): u256
-
-
-
-
-
-Implementation
-
-
-public fun val(decimal: &Decimal256): u256 {
- decimal.val
-}
-
-
-
-
-
-
-
-
-## Function `is_same`
-
-
-
-public fun is_same(left: &decimal256::Decimal256, right: &decimal256::Decimal256): bool
-
-
-
-
-
-Implementation
-
-
-public fun is_same(left: &Decimal256, right: &Decimal256): bool {
- left.val == right.val
-}
-
-
-
-
-
-
-
-
-## Function `from_string`
-
-
-
-public fun from_string(num: &string::String): decimal256::Decimal256
-
-
-
-
-
-Implementation
-
-
-public fun from_string(num: &String): Decimal256 {
- let vec = string::bytes(num);
- let len = vector::length(vec);
-
- let cursor = 0;
- let dot_index = 0;
- let val: u256 = 0;
- while (cursor < len) {
- let s = *vector::borrow(vec, cursor);
- cursor = cursor + 1;
-
- // find `.` position
- if (s == 46) continue;
-
- val = val * 10;
- assert!(s >= 48 && s <= 57, error::invalid_argument(EFAILED_TO_DESERIALIZE));
-
- let n = (s - 48 as u256);
- val = val + n;
-
- if (cursor == dot_index + 1) {
- // use `<` not `<=` to safely check "out of range"
- // (i.e. to avoid fractional part checking)
- assert!(val < MAX_INTEGER_PART, error::invalid_argument(EOUT_OF_RANGE));
-
- dot_index = dot_index + 1;
- };
- };
-
- // ignore fractional part longer than `FRACTIONAL_LENGTH`
- let val = if (dot_index == len) {
- val * pow(10, FRACTIONAL_LENGTH)
- } else {
- let fractional_length = len - dot_index - 1;
- if (fractional_length > FRACTIONAL_LENGTH) {
- val / pow(10, fractional_length - FRACTIONAL_LENGTH)
- } else {
- val * pow(10, FRACTIONAL_LENGTH - fractional_length)
- }
- };
-
- new(val)
-}
-
-
-
-
-
-
-
-
-## Function `pow`
-
-
-
-fun pow(num: u256, pow_amount: u64): u256
-
-
-
-
-
-Implementation
-
-
-fun pow(num: u256, pow_amount: u64): u256 {
- let index = 0;
- let val = 1;
- while (index < pow_amount) {
- val = val * num;
- index = index + 1;
- };
-
- val
-}
-
-
-
-
-
diff --git a/initia_stdlib/doc/dex.md b/initia_stdlib/doc/dex.md
index 04cf49c..f4b8c74 100644
--- a/initia_stdlib/doc/dex.md
+++ b/initia_stdlib/doc/dex.md
@@ -54,8 +54,6 @@
- [Function `get_timestamp_from_weight`](#0x1_dex_get_timestamp_from_weight)
- [Function `unpack_pair_response`](#0x1_dex_unpack_pair_response)
- [Function `unpack_current_weight_response`](#0x1_dex_unpack_current_weight_response)
-- [Function `check_chain_permission`](#0x1_dex_check_chain_permission)
-- [Function `init_module`](#0x1_dex_init_module)
- [Function `create_pair_script`](#0x1_dex_create_pair_script)
- [Function `create_lbp_pair_script`](#0x1_dex_create_lbp_pair_script)
- [Function `update_swap_fee_rate`](#0x1_dex_update_swap_fee_rate)
@@ -69,22 +67,16 @@
- [Function `swap`](#0x1_dex_swap)
- [Function `create_pair`](#0x1_dex_create_pair)
- [Function `provide_liquidity`](#0x1_dex_provide_liquidity)
-- [Function `coin_address`](#0x1_dex_coin_address)
-- [Function `check_lbp_ended`](#0x1_dex_check_lbp_ended)
-- [Function `generate_pair_key`](#0x1_dex_generate_pair_key)
-- [Function `get_weight`](#0x1_dex_get_weight)
- [Function `pool_info`](#0x1_dex_pool_info)
- [Function `swap_simulation`](#0x1_dex_swap_simulation)
- [Function `swap_simulation_given_out`](#0x1_dex_swap_simulation_given_out)
- [Function `pool_metadata`](#0x1_dex_pool_metadata)
-- [Function `pow`](#0x1_dex_pow)
-- [Function `ln`](#0x1_dex_ln)
-- [Function `mul_decimal128s`](#0x1_dex_mul_decimal128s)
-use 0x1::block;
+use 0x1::bigdecimal;
+use 0x1::biguint;
+use 0x1::block;
use 0x1::coin;
-use 0x1::decimal128;
use 0x1::error;
use 0x1::event;
use 0x1::fungible_asset;
@@ -110,8 +102,7 @@ Pool configuration
-
-Fields
+##### Fields
@@ -128,7 +119,7 @@ Pool configuration
-
-
swap_fee_rate: decimal128::Decimal128
+swap_fee_rate: bigdecimal::BigDecimal
-
@@ -136,8 +127,6 @@ Pool configuration
-
-
## Resource `Pool`
@@ -149,8 +138,7 @@ Pool configuration
-
-Fields
+##### Fields
@@ -169,8 +157,6 @@ Pool configuration
-
-
## Struct `Weights`
@@ -182,8 +168,7 @@ Pool configuration
-
-Fields
+##### Fields
@@ -202,8 +187,6 @@ Pool configuration
-
-
## Struct `Weight`
@@ -215,25 +198,24 @@ Pool configuration
-
-Fields
+##### Fields
-
-
coin_a_weight: decimal128::Decimal128
+coin_a_weight: bigdecimal::BigDecimal
-
-
-
coin_b_weight: decimal128::Decimal128
+coin_b_weight: bigdecimal::BigDecimal
-
-
-
timestamp: u64
+timestamp: u64
-
@@ -241,8 +223,6 @@ Pool configuration
-
-
## Struct `PairKey`
@@ -255,8 +235,7 @@ Key for pair
-
-Fields
+##### Fields
@@ -281,8 +260,6 @@ Key for pair
-
-
## Struct `PairResponse`
@@ -294,8 +271,7 @@ Key for pair
-
-Fields
+##### Fields
@@ -324,7 +300,7 @@ Key for pair
-
-
swap_fee_rate: decimal128::Decimal128
+swap_fee_rate: bigdecimal::BigDecimal
-
@@ -332,8 +308,6 @@ Key for pair
-
-
## Struct `PairByDenomResponse`
@@ -345,8 +319,7 @@ Key for pair
-
-Fields
+##### Fields
@@ -375,7 +348,7 @@ Key for pair
-
-
swap_fee_rate: decimal128::Decimal128
+swap_fee_rate: bigdecimal::BigDecimal
-
@@ -383,8 +356,6 @@ Key for pair
-
-
## Resource `CoinCapabilities`
@@ -397,8 +368,7 @@ Coin capabilities
-
-Fields
+##### Fields
@@ -423,8 +393,6 @@ Coin capabilities
-
-
## Struct `ProvideEvent`
@@ -438,8 +406,7 @@ Event emitted when provide liquidity.
-
-Fields
+##### Fields
@@ -482,8 +449,6 @@ Event emitted when provide liquidity.
-
-
## Struct `WithdrawEvent`
@@ -497,8 +462,7 @@ Event emitted when withdraw liquidity.
-
-Fields
+##### Fields
@@ -541,8 +505,6 @@ Event emitted when withdraw liquidity.
-
-
## Struct `SwapEvent`
@@ -556,8 +518,7 @@ Event emitted when swap token.
-
-Fields
+##### Fields
@@ -600,8 +561,6 @@ Event emitted when swap token.
-
-
## Struct `SingleAssetProvideEvent`
@@ -614,8 +573,7 @@ Event emitted when swap token.
-
-Fields
+##### Fields
@@ -664,8 +622,6 @@ Event emitted when swap token.
-
-
## Struct `PoolInfoResponse`
@@ -677,8 +633,7 @@ Event emitted when swap token.
-
-Fields
+##### Fields
@@ -703,8 +658,6 @@ Event emitted when swap token.
-
-
## Struct `ConfigResponse`
@@ -716,8 +669,7 @@ Event emitted when swap token.
-
-Fields
+##### Fields
@@ -728,7 +680,7 @@ Event emitted when swap token.
-
-
swap_fee_rate: decimal128::Decimal128
+swap_fee_rate: bigdecimal::BigDecimal
-
@@ -736,8 +688,6 @@ Event emitted when swap token.
-
-
## Struct `CurrentWeightResponse`
@@ -749,19 +699,18 @@ Event emitted when swap token.
-
-Fields
+##### Fields
-
-
coin_a_weight: decimal128::Decimal128
+coin_a_weight: bigdecimal::BigDecimal
-
-
-
coin_b_weight: decimal128::Decimal128
+coin_b_weight: bigdecimal::BigDecimal
-
@@ -769,8 +718,6 @@ Event emitted when swap token.
-
-
## Struct `PairMetadataResponse`
@@ -782,8 +729,7 @@ Event emitted when swap token.
-
-Fields
+##### Fields
@@ -802,8 +748,6 @@ Event emitted when swap token.
-
-
## Struct `PairDenomResponse`
@@ -815,8 +759,7 @@ Event emitted when swap token.
-
-Fields
+##### Fields
@@ -835,8 +778,6 @@ Event emitted when swap token.
-
-
## Struct `CreatePairEvent`
@@ -849,8 +790,7 @@ Event emitted when swap token.
-
-Fields
+##### Fields
@@ -879,7 +819,7 @@ Event emitted when swap token.
-
-
swap_fee_rate: decimal128::Decimal128
+swap_fee_rate: bigdecimal::BigDecimal
-
@@ -887,8 +827,6 @@ Event emitted when swap token.
-
-
## Struct `SwapFeeUpdateEvent`
@@ -901,8 +839,7 @@ Event emitted when swap token.
-
-Fields
+##### Fields
@@ -925,7 +862,7 @@ Event emitted when swap token.
-
-
swap_fee_rate: decimal128::Decimal128
+swap_fee_rate: bigdecimal::BigDecimal
-
@@ -933,8 +870,6 @@ Event emitted when swap token.
-
-
## Resource `ModuleStore`
@@ -947,8 +882,7 @@ Module store for storing pair infos
-
-Fields
+##### Fields
@@ -967,13 +901,21 @@ Module store for storing pair infos
-
-
## Constants
+
+
+Only chain can execute.
+
+
+const EUNAUTHORIZED: u64 = 7;
+
+
+
+
Wrong coin type given
@@ -984,6 +926,16 @@ Wrong coin type given
+
+
+Weights sum must be 1.0
+
+
+const EINVALID_WEIGHTS: u64 = 21;
+
+
+
+
LBP is not ended, only swap allowed
@@ -1093,16 +1045,6 @@ All start_after must be provided or not
-
-
-Only chain can execute.
-
-
-const EUNAUTHORIZED: u64 = 7;
-
-
-
-
end time must be larger than start time
@@ -1113,21 +1055,22 @@ end time must be larger than start time
-
+
-Can not withdraw zero liquidity
+Zero amount in the swap simulation is not allowed
-const EZERO_LIQUIDITY: u64 = 2;
+const EZERO_AMOUNT_IN: u64 = 20;
-
+
+Can not withdraw zero liquidity
-const MAX_FEE_RATE: u128 = 50000000000000000;
+const EZERO_LIQUIDITY: u64 = 2;
@@ -1146,7 +1089,7 @@ Can not withdraw zero liquidity
Result Precision of pow
and ln
function
-const PRECISION: u128 = 100000;
+const PRECISION: u64 = 100000;
@@ -1163,28 +1106,20 @@ Result Precision of pow
and ln
function
-
-Implementation
+##### Implementation
-public fun get_pair_metadata(
- pair: Object<Config>,
-): PairMetadataResponse acquires Pool {
- let pool = borrow_global_mut<Pool>(object::object_address(pair));
+public fun get_pair_metadata(pair: Object<Config>): PairMetadataResponse acquires Pool {
+ let pool = borrow_global_mut<Pool>(object::object_address(&pair));
let coin_a_metadata = fungible_asset::store_metadata(pool.coin_a_store);
let coin_b_metadata = fungible_asset::store_metadata(pool.coin_b_store);
- PairMetadataResponse {
- coin_a_metadata,
- coin_b_metadata,
- }
+ PairMetadataResponse { coin_a_metadata, coin_b_metadata }
}
-
-
## Function `get_pair_denom`
@@ -1197,26 +1132,21 @@ Result Precision of pow
and ln
function
-
-Implementation
+##### Implementation
-public fun get_pair_denom(
- pair: Object<Config>,
-): PairDenomResponse acquires Pool {
+public fun get_pair_denom(pair: Object<Config>): PairDenomResponse acquires Pool {
let pair_metadata = get_pair_metadata(pair);
PairDenomResponse {
coin_a_denom: coin::metadata_to_denom(pair_metadata.coin_a_metadata),
- coin_b_denom: coin::metadata_to_denom(pair_metadata.coin_b_metadata),
+ coin_b_denom: coin::metadata_to_denom(pair_metadata.coin_b_metadata)
}
}
-
-
## Function `get_spot_price`
@@ -1226,45 +1156,43 @@ https://balancer.fi/whitepaper.pdf (2)
#[view]
-public fun get_spot_price(pair: object::Object<dex::Config>, base_coin: object::Object<fungible_asset::Metadata>): decimal128::Decimal128
+public fun get_spot_price(pair: object::Object<dex::Config>, base_coin: object::Object<fungible_asset::Metadata>): bigdecimal::BigDecimal
-
-Implementation
+##### Implementation
public fun get_spot_price(
- pair: Object<Config>,
- base_coin: Object<Metadata>,
-): Decimal128 acquires Config, Pool {
- let (coin_a_pool, coin_b_pool, coin_a_weight, coin_b_weight, _) = pool_info(pair, false);
+ pair: Object<Config>, base_coin: Object<Metadata>
+): BigDecimal acquires Config, Pool {
+ let (coin_a_pool, coin_b_pool, coin_a_weight, coin_b_weight, _) =
+ pool_info(pair, false);
let pair_key = generate_pair_key(pair);
- let base_addr = object::object_address(base_coin);
+ let base_addr = object::object_address(&base_coin);
assert!(
base_addr == pair_key.coin_a || base_addr == pair_key.coin_b,
- error::invalid_argument(ECOIN_TYPE),
+ error::invalid_argument(ECOIN_TYPE)
);
let is_base_a = base_addr == pair_key.coin_a;
- let (base_pool, quote_pool, base_weight, quote_weight) = if (is_base_a) {
- (coin_a_pool, coin_b_pool, coin_a_weight, coin_b_weight)
- } else {
- (coin_b_pool, coin_a_pool, coin_b_weight, coin_a_weight)
- };
+ let (base_pool, quote_pool, base_weight, quote_weight) =
+ if (is_base_a) {
+ (coin_a_pool, coin_b_pool, coin_a_weight, coin_b_weight)
+ } else {
+ (coin_b_pool, coin_a_pool, coin_b_weight, coin_a_weight)
+ };
- decimal128::from_ratio_u64(
- decimal128::mul_u64(&base_weight, quote_pool),
- decimal128::mul_u64("e_weight, base_pool),
+ bigdecimal::div(
+ bigdecimal::mul_by_u64(base_weight, quote_pool),
+ bigdecimal::mul_by_u64(quote_weight, base_pool)
)
}
-
-
## Function `get_spot_price_by_denom`
@@ -1272,19 +1200,17 @@ https://balancer.fi/whitepaper.pdf (2)
#[view]
-public fun get_spot_price_by_denom(pair_denom: string::String, base_coin: string::String): decimal128::Decimal128
+public fun get_spot_price_by_denom(pair_denom: string::String, base_coin: string::String): bigdecimal::BigDecimal
-
-Implementation
+##### Implementation
public fun get_spot_price_by_denom(
- pair_denom: String,
- base_coin: String,
-): Decimal128 acquires Config, Pool {
+ pair_denom: String, base_coin: String
+): BigDecimal acquires Config, Pool {
let pair_metadata = coin::denom_to_metadata(pair_denom);
let base_metadata = coin::denom_to_metadata(base_coin);
get_spot_price(object::convert(pair_metadata), base_metadata)
@@ -1293,8 +1219,6 @@ https://balancer.fi/whitepaper.pdf (2)
-
-
## Function `get_swap_simulation`
@@ -1308,36 +1232,35 @@ Return swap simulation result
-
-Implementation
+##### Implementation
public fun get_swap_simulation(
- pair: Object<Config>,
- offer_metadata: Object<Metadata>,
- offer_amount: u64,
+ pair: Object<Config>, offer_metadata: Object<Metadata>, offer_amount: u64
): u64 acquires Config, Pool {
let pair_key = generate_pair_key(pair);
- let offer_address = object::object_address(offer_metadata);
+ let offer_address = object::object_address(&offer_metadata);
assert!(
offer_address == pair_key.coin_a || offer_address == pair_key.coin_b,
- error::invalid_argument(ECOIN_TYPE),
+ error::invalid_argument(ECOIN_TYPE)
);
let is_offer_a = offer_address == pair_key.coin_a;
let (pool_a, pool_b, weight_a, weight_b, swap_fee_rate) = pool_info(pair, true);
- let (offer_pool, return_pool, offer_weight, return_weight) = if (is_offer_a) {
- (pool_a, pool_b, weight_a, weight_b)
- } else {
- (pool_b, pool_a, weight_b, weight_a)
- };
- let (return_amount, _fee_amount) = swap_simulation(
- offer_pool,
- return_pool,
- offer_weight,
- return_weight,
- offer_amount,
- swap_fee_rate,
- );
+ let (offer_pool, return_pool, offer_weight, return_weight) =
+ if (is_offer_a) {
+ (pool_a, pool_b, weight_a, weight_b)
+ } else {
+ (pool_b, pool_a, weight_b, weight_a)
+ };
+ let (return_amount, _fee_amount) =
+ swap_simulation(
+ offer_pool,
+ return_pool,
+ offer_weight,
+ return_weight,
+ offer_amount,
+ swap_fee_rate
+ );
return_amount
}
@@ -1345,8 +1268,6 @@ Return swap simulation result
-
-
## Function `get_swap_simulation_by_denom`
@@ -1359,25 +1280,24 @@ Return swap simulation result
-
-Implementation
+##### Implementation
public fun get_swap_simulation_by_denom(
- pair_denom: String,
- offer_denom: String,
- offer_amount: u64,
+ pair_denom: String, offer_denom: String, offer_amount: u64
): u64 acquires Config, Pool {
let pair_metadata = coin::denom_to_metadata(pair_denom);
let offer_metadata = coin::denom_to_metadata(offer_denom);
- get_swap_simulation(object::convert(pair_metadata), offer_metadata, offer_amount)
+ get_swap_simulation(
+ object::convert(pair_metadata),
+ offer_metadata,
+ offer_amount
+ )
}
-
-
## Function `get_swap_simulation_given_out`
@@ -1391,36 +1311,35 @@ Return swap simulation result
-
-Implementation
+##### Implementation
public fun get_swap_simulation_given_out(
- pair: Object<Config>,
- offer_metadata: Object<Metadata>,
- return_amount: u64,
+ pair: Object<Config>, offer_metadata: Object<Metadata>, return_amount: u64
): u64 acquires Config, Pool {
let pair_key = generate_pair_key(pair);
- let offer_address = object::object_address(offer_metadata);
+ let offer_address = object::object_address(&offer_metadata);
assert!(
offer_address == pair_key.coin_a || offer_address == pair_key.coin_b,
- error::invalid_argument(ECOIN_TYPE),
+ error::invalid_argument(ECOIN_TYPE)
);
let is_offer_a = offer_address == pair_key.coin_a;
let (pool_a, pool_b, weight_a, weight_b, swap_fee_rate) = pool_info(pair, true);
- let (offer_pool, return_pool, offer_weight, return_weight) = if (is_offer_a) {
- (pool_a, pool_b, weight_a, weight_b)
- } else {
- (pool_b, pool_a, weight_b, weight_a)
- };
- let (offer_amount, _fee_amount) = swap_simulation_given_out(
- offer_pool,
- return_pool,
- offer_weight,
- return_weight,
- return_amount,
- swap_fee_rate,
- );
+ let (offer_pool, return_pool, offer_weight, return_weight) =
+ if (is_offer_a) {
+ (pool_a, pool_b, weight_a, weight_b)
+ } else {
+ (pool_b, pool_a, weight_b, weight_a)
+ };
+ let (offer_amount, _fee_amount) =
+ swap_simulation_given_out(
+ offer_pool,
+ return_pool,
+ offer_weight,
+ return_weight,
+ return_amount,
+ swap_fee_rate
+ );
offer_amount
}
@@ -1428,8 +1347,6 @@ Return swap simulation result
-
-
## Function `get_swap_simulation_given_out_by_denom`
@@ -1442,25 +1359,24 @@ Return swap simulation result
-
-Implementation
+##### Implementation
public fun get_swap_simulation_given_out_by_denom(
- pair_denom: String,
- offer_denom: String,
- return_amount: u64,
+ pair_denom: String, offer_denom: String, return_amount: u64
): u64 acquires Config, Pool {
let pair_metadata = coin::denom_to_metadata(pair_denom);
let offer_metadata = coin::denom_to_metadata(offer_denom);
- get_swap_simulation_given_out(object::convert(pair_metadata), offer_metadata, return_amount)
+ get_swap_simulation_given_out(
+ object::convert(pair_metadata),
+ offer_metadata,
+ return_amount
+ )
}
-
-
## Function `get_pool_info`
@@ -1474,25 +1390,22 @@ get pool info
-
-Implementation
+##### Implementation
public fun get_pool_info(pair: Object<Config>): PoolInfoResponse acquires Pool {
- let pair_addr = object::object_address(pair);
+ let pair_addr = object::object_address(&pair);
let pool = borrow_global<Pool>(pair_addr);
PoolInfoResponse {
coin_a_amount: fungible_asset::balance(pool.coin_a_store),
coin_b_amount: fungible_asset::balance(pool.coin_b_store),
- total_share: option::extract(&mut fungible_asset::supply(pair)),
+ total_share: option::extract(&mut fungible_asset::supply(pair))
}
}
-
-
## Function `get_pool_info_by_denom`
@@ -1506,8 +1419,7 @@ get pool info
-
-Implementation
+##### Implementation
public fun get_pool_info_by_denom(pair_denom: String): PoolInfoResponse acquires Pool {
@@ -1518,8 +1430,6 @@ get pool info
-
-
## Function `get_config`
@@ -1533,25 +1443,19 @@ get config
-
-Implementation
+##### Implementation
public fun get_config(pair: Object<Config>): ConfigResponse acquires Config {
- let pair_addr = object::object_address(pair);
+ let pair_addr = object::object_address(&pair);
let config = borrow_global<Config>(pair_addr);
- ConfigResponse {
- weights: config.weights,
- swap_fee_rate: config.swap_fee_rate,
- }
+ ConfigResponse { weights: config.weights, swap_fee_rate: config.swap_fee_rate }
}
-
-
## Function `get_config_by_denom`
@@ -1565,8 +1469,7 @@ get config
-
-Implementation
+##### Implementation
public fun get_config_by_denom(pair_denom: String): ConfigResponse acquires Config {
@@ -1577,8 +1480,6 @@ get config
-
-
## Function `get_current_weight`
@@ -1591,25 +1492,19 @@ get config
-
-Implementation
+##### Implementation
public fun get_current_weight(pair: Object<Config>): CurrentWeightResponse acquires Config {
- let pair_addr = object::object_address(pair);
+ let pair_addr = object::object_address(&pair);
let config = borrow_global<Config>(pair_addr);
let (coin_a_weight, coin_b_weight) = get_weight(&config.weights);
- CurrentWeightResponse {
- coin_a_weight,
- coin_b_weight,
- }
+ CurrentWeightResponse { coin_a_weight, coin_b_weight }
}
-
-
## Function `get_current_weight_by_denom`
@@ -1622,11 +1517,12 @@ get config
-
-Implementation
+##### Implementation
-public fun get_current_weight_by_denom(pair_denom: String): CurrentWeightResponse acquires Config {
+public fun get_current_weight_by_denom(
+ pair_denom: String
+): CurrentWeightResponse acquires Config {
let pair_metadata = coin::denom_to_metadata(pair_denom);
get_current_weight(object::convert(pair_metadata))
}
@@ -1634,8 +1530,6 @@ get config
-
-
## Function `get_all_pairs`
@@ -1648,52 +1542,55 @@ get config
-
-Implementation
+##### Implementation
public fun get_all_pairs(
coin_a_start_after: Option<address>,
coin_b_start_after: Option<address>,
liquidity_token_start_after: Option<address>,
- limit: u8,
+ limit: u8
): vector<PairResponse> acquires ModuleStore {
if (limit > MAX_LIMIT) {
limit = MAX_LIMIT;
};
assert!(
- option::is_some(&coin_a_start_after) == option::is_some(&coin_b_start_after)
- && option::is_some(&coin_b_start_after) == option::is_some(&liquidity_token_start_after),
+ option::is_some(&coin_a_start_after)
+ == option::is_some(&coin_b_start_after)
+ && option::is_some(&coin_b_start_after)
+ == option::is_some(&liquidity_token_start_after),
ESTART_AFTER
);
let module_store = borrow_global<ModuleStore>(@initia_std);
- let start_after = if (option::is_some(&coin_a_start_after)) {
- option::some(PairKey {
- coin_a: option::extract(&mut coin_a_start_after),
- coin_b: option::extract(&mut coin_b_start_after),
- liquidity_token: option::extract(&mut liquidity_token_start_after),
- })
- } else {
- option::some(PairKey {
- coin_a: @0x0,
- coin_b: @0x0,
- liquidity_token: @0x0,
- })
- };
+ let start_after =
+ if (option::is_some(&coin_a_start_after)) {
+ option::some(
+ PairKey {
+ coin_a: option::extract(&mut coin_a_start_after),
+ coin_b: option::extract(&mut coin_b_start_after),
+ liquidity_token: option::extract(&mut liquidity_token_start_after)
+ }
+ )
+ } else {
+ option::some(
+ PairKey { coin_a: @0x0, coin_b: @0x0, liquidity_token: @0x0 }
+ )
+ };
let res = vector[];
let pairs_iter = table::iter(
&module_store.pairs,
start_after,
option::none(),
- 1,
+ 1
);
- while (vector::length(&res) < (limit as u64) && table::prepare<PairKey, PairResponse>(&mut pairs_iter)) {
- let (key, value) = table::next<PairKey, PairResponse>(&mut pairs_iter);
+ while (vector::length(&res) < (limit as u64)
+ && table::prepare<PairKey, PairResponse>(pairs_iter)) {
+ let (key, value) = table::next<PairKey, PairResponse>(pairs_iter);
if (&key != option::borrow(&start_after)) {
vector::push_back(&mut res, *value)
}
@@ -1705,8 +1602,6 @@ get config
-
-
## Function `get_all_pairs_by_denom`
@@ -1719,63 +1614,82 @@ get config
-
-Implementation
+##### Implementation
public fun get_all_pairs_by_denom(
coin_a_start_after: Option<String>,
coin_b_start_after: Option<String>,
liquidity_token_start_after: Option<String>,
- limit: u8,
+ limit: u8
): vector<PairByDenomResponse> acquires ModuleStore {
if (limit > MAX_LIMIT) {
limit = MAX_LIMIT;
};
assert!(
- option::is_some(&coin_a_start_after) == option::is_some(&coin_b_start_after)
- && option::is_some(&coin_b_start_after) == option::is_some(&liquidity_token_start_after),
+ option::is_some(&coin_a_start_after)
+ == option::is_some(&coin_b_start_after)
+ && option::is_some(&coin_b_start_after)
+ == option::is_some(&liquidity_token_start_after),
ESTART_AFTER
);
let module_store = borrow_global<ModuleStore>(@initia_std);
- let start_after = if (option::is_some(&coin_a_start_after)) {
- let coin_a_start_after = coin::denom_to_metadata(option::extract(&mut coin_a_start_after));
- let coin_b_start_after = coin::denom_to_metadata(option::extract(&mut coin_b_start_after));
- let liquidity_token_start_after = coin::denom_to_metadata(option::extract(&mut liquidity_token_start_after));
- option::some(PairKey {
- coin_a: object::object_address(coin_a_start_after),
- coin_b: object::object_address(coin_b_start_after),
- liquidity_token: object::object_address(liquidity_token_start_after),
- })
- } else {
- option::some(PairKey {
- coin_a: @0x0,
- coin_b: @0x0,
- liquidity_token: @0x0,
- })
- };
+ let start_after =
+ if (option::is_some(&coin_a_start_after)) {
+ let coin_a_start_after =
+ coin::denom_to_metadata(option::extract(&mut coin_a_start_after));
+ let coin_b_start_after =
+ coin::denom_to_metadata(option::extract(&mut coin_b_start_after));
+ let liquidity_token_start_after =
+ coin::denom_to_metadata(
+ option::extract(&mut liquidity_token_start_after)
+ );
+ option::some(
+ PairKey {
+ coin_a: object::object_address(&coin_a_start_after),
+ coin_b: object::object_address(&coin_b_start_after),
+ liquidity_token: object::object_address(
+ &liquidity_token_start_after
+ )
+ }
+ )
+ } else {
+ option::some(
+ PairKey { coin_a: @0x0, coin_b: @0x0, liquidity_token: @0x0 }
+ )
+ };
let res = vector[];
let pairs_iter = table::iter(
&module_store.pairs,
start_after,
option::none(),
- 1,
+ 1
);
- while (vector::length(&res) < (limit as u64) && table::prepare<PairKey, PairResponse>(&mut pairs_iter)) {
- let (key, value) = table::next<PairKey, PairResponse>(&mut pairs_iter);
+ while (vector::length(&res) < (limit as u64)
+ && table::prepare<PairKey, PairResponse>(pairs_iter)) {
+ let (key, value) = table::next<PairKey, PairResponse>(pairs_iter);
if (&key != option::borrow(&start_after)) {
- vector::push_back(&mut res, PairByDenomResponse {
- coin_a: coin::metadata_to_denom(object::address_to_object(value.coin_a)),
- coin_b: coin::metadata_to_denom(object::address_to_object(value.coin_b)),
- liquidity_token: coin::metadata_to_denom(object::address_to_object(value.liquidity_token)),
- weights: value.weights,
- swap_fee_rate: value.swap_fee_rate,
- })
+ vector::push_back(
+ &mut res,
+ PairByDenomResponse {
+ coin_a: coin::metadata_to_denom(
+ object::address_to_object(value.coin_a)
+ ),
+ coin_b: coin::metadata_to_denom(
+ object::address_to_object(value.coin_b)
+ ),
+ liquidity_token: coin::metadata_to_denom(
+ object::address_to_object(value.liquidity_token)
+ ),
+ weights: value.weights,
+ swap_fee_rate: value.swap_fee_rate
+ }
+ )
}
};
@@ -1785,8 +1699,6 @@ get config
-
-
## Function `get_pairs`
@@ -1799,15 +1711,14 @@ get config
-
-Implementation
+##### Implementation
public fun get_pairs(
coin_a: address,
coin_b: address,
start_after: Option<address>,
- limit: u8,
+ limit: u8
): vector<PairResponse> acquires ModuleStore {
if (limit > MAX_LIMIT) {
limit = MAX_LIMIT;
@@ -1815,31 +1726,32 @@ get config
let module_store = borrow_global<ModuleStore>(@initia_std);
- let start_after = if (option::is_some(&start_after)) {
- option::some(PairKey {
- coin_a,
- coin_b,
- liquidity_token: option::extract(&mut start_after),
- })
- } else {
- option::some(PairKey {
- coin_a,
- coin_b,
- liquidity_token: @0x0,
- })
- };
+ let start_after =
+ if (option::is_some(&start_after)) {
+ option::some(
+ PairKey {
+ coin_a,
+ coin_b,
+ liquidity_token: option::extract(&mut start_after)
+ }
+ )
+ } else {
+ option::some(PairKey { coin_a, coin_b, liquidity_token: @0x0 })
+ };
let res = vector[];
let pairs_iter = table::iter(
&module_store.pairs,
start_after,
option::none(),
- 1,
+ 1
);
- while (vector::length(&res) < (limit as u64) && table::prepare<PairKey, PairResponse>(&mut pairs_iter)) {
- let (key, value) = table::next<PairKey, PairResponse>(&mut pairs_iter);
- if (coin_a != key.coin_a || coin_b != key.coin_b) break;
+ while (vector::length(&res) < (limit as u64)
+ && table::prepare<PairKey, PairResponse>(pairs_iter)) {
+ let (key, value) = table::next<PairKey, PairResponse>(pairs_iter);
+ if (coin_a != key.coin_a || coin_b != key.coin_b)
+ break;
if (&key != option::borrow(&start_after)) {
vector::push_back(&mut res, *value)
}
@@ -1851,8 +1763,6 @@ get config
-
-
## Function `get_coin_a_amount_from_pool_info_response`
@@ -1864,19 +1774,18 @@ get config
-
-Implementation
+##### Implementation
-public fun get_coin_a_amount_from_pool_info_response(res: &PoolInfoResponse): u64 {
+public fun get_coin_a_amount_from_pool_info_response(
+ res: &PoolInfoResponse
+): u64 {
res.coin_a_amount
}
-
-
## Function `get_coin_b_amount_from_pool_info_response`
@@ -1888,19 +1797,18 @@ get config
-
-Implementation
+##### Implementation
-public fun get_coin_b_amount_from_pool_info_response(res: &PoolInfoResponse): u64 {
+public fun get_coin_b_amount_from_pool_info_response(
+ res: &PoolInfoResponse
+): u64 {
res.coin_b_amount
}
-
-
## Function `get_total_share_from_pool_info_response`
@@ -1912,43 +1820,41 @@ get config
-
-Implementation
+##### Implementation
-public fun get_total_share_from_pool_info_response(res: &PoolInfoResponse): u128 {
+public fun get_total_share_from_pool_info_response(
+ res: &PoolInfoResponse
+): u128 {
res.total_share
}
-
-
## Function `get_swap_fee_rate_from_config_response`
-public fun get_swap_fee_rate_from_config_response(res: &dex::ConfigResponse): decimal128::Decimal128
+public fun get_swap_fee_rate_from_config_response(res: &dex::ConfigResponse): bigdecimal::BigDecimal
-
-Implementation
+##### Implementation
-public fun get_swap_fee_rate_from_config_response(res: &ConfigResponse): Decimal128 {
+public fun get_swap_fee_rate_from_config_response(
+ res: &ConfigResponse
+): BigDecimal {
res.swap_fee_rate
}
-
-
## Function `get_weight_before_from_config_response`
@@ -1960,19 +1866,18 @@ get config
-
-Implementation
+##### Implementation
-public fun get_weight_before_from_config_response(res: &ConfigResponse): Weight {
+public fun get_weight_before_from_config_response(
+ res: &ConfigResponse
+): Weight {
res.weights.weights_before
}
-
-
## Function `get_weight_after_from_config_response`
@@ -1984,8 +1889,7 @@ get config
-
-Implementation
+##### Implementation
public fun get_weight_after_from_config_response(res: &ConfigResponse): Weight {
@@ -1995,56 +1899,48 @@ get config
-
-
## Function `get_coin_a_weight_from_weight`
-public fun get_coin_a_weight_from_weight(weight: &dex::Weight): decimal128::Decimal128
+public fun get_coin_a_weight_from_weight(weight: &dex::Weight): bigdecimal::BigDecimal
-
-Implementation
+##### Implementation
-public fun get_coin_a_weight_from_weight(weight: &Weight): Decimal128 {
+public fun get_coin_a_weight_from_weight(weight: &Weight): BigDecimal {
weight.coin_a_weight
}
-
-
## Function `get_coin_b_weight_from_weight`
-public fun get_coin_b_weight_from_weight(weight: &dex::Weight): decimal128::Decimal128
+public fun get_coin_b_weight_from_weight(weight: &dex::Weight): bigdecimal::BigDecimal
-
-Implementation
+##### Implementation
-public fun get_coin_b_weight_from_weight(weight: &Weight): Decimal128 {
+public fun get_coin_b_weight_from_weight(weight: &Weight): BigDecimal {
weight.coin_b_weight
}
-
-
## Function `get_timestamp_from_weight`
@@ -2056,35 +1952,33 @@ get config
-
-Implementation
+##### Implementation
public fun get_timestamp_from_weight(weight: &Weight): u64 {
- weight.timestamp
+ weight.timestamp
}
-
-
## Function `unpack_pair_response`
-public fun unpack_pair_response(pair_response: &dex::PairResponse): (address, address, address, dex::Weights, decimal128::Decimal128)
+public fun unpack_pair_response(pair_response: &dex::PairResponse): (address, address, address, dex::Weights, bigdecimal::BigDecimal)
-
-Implementation
+##### Implementation
-public fun unpack_pair_response(pair_response: &PairResponse): (address, address, address, Weights, Decimal128) {
+public fun unpack_pair_response(
+ pair_response: &PairResponse
+): (address, address, address, Weights, BigDecimal) {
(
pair_response.coin_a,
pair_response.coin_b,
@@ -2097,140 +1991,88 @@ get config
-
-
## Function `unpack_current_weight_response`
-public fun unpack_current_weight_response(current_weight_response: &dex::CurrentWeightResponse): (decimal128::Decimal128, decimal128::Decimal128)
+public fun unpack_current_weight_response(current_weight_response: &dex::CurrentWeightResponse): (bigdecimal::BigDecimal, bigdecimal::BigDecimal)
-
-Implementation
+##### Implementation
-public fun unpack_current_weight_response(current_weight_response: &CurrentWeightResponse): (Decimal128, Decimal128) {
- (
- current_weight_response.coin_a_weight,
- current_weight_response.coin_b_weight,
- )
+public fun unpack_current_weight_response(
+ current_weight_response: &CurrentWeightResponse
+): (BigDecimal, BigDecimal) {
+ (current_weight_response.coin_a_weight, current_weight_response.coin_b_weight)
}
-
-
-
-
-## Function `check_chain_permission`
-
-Check signer is chain
-
-
-fun check_chain_permission(chain: &signer)
-
-
-
-
-
-Implementation
-
-
-fun check_chain_permission(chain: &signer) {
- assert!(signer::address_of(chain) == @initia_std, error::permission_denied(EUNAUTHORIZED));
-}
-
-
-
-
-
-
-
-
-## Function `init_module`
-
-
-
-fun init_module(chain: &signer)
-
-
-
-
-
-Implementation
-
-
-fun init_module(chain: &signer) {
- move_to(chain, ModuleStore {
- pairs: table::new<PairKey, PairResponse>(),
- pair_count: 0,
- });
-}
-
-
-
-
-
-
## Function `create_pair_script`
-public entry fun create_pair_script(creator: &signer, name: string::String, symbol: string::String, swap_fee_rate: decimal128::Decimal128, coin_a_weight: decimal128::Decimal128, coin_b_weight: decimal128::Decimal128, coin_a_metadata: object::Object<fungible_asset::Metadata>, coin_b_metadata: object::Object<fungible_asset::Metadata>, coin_a_amount: u64, coin_b_amount: u64)
+public entry fun create_pair_script(creator: &signer, name: string::String, symbol: string::String, swap_fee_rate: bigdecimal::BigDecimal, coin_a_weight: bigdecimal::BigDecimal, coin_b_weight: bigdecimal::BigDecimal, coin_a_metadata: object::Object<fungible_asset::Metadata>, coin_b_metadata: object::Object<fungible_asset::Metadata>, coin_a_amount: u64, coin_b_amount: u64)
-
-Implementation
+##### Implementation
public entry fun create_pair_script(
creator: &signer,
name: String,
symbol: String,
- swap_fee_rate: Decimal128,
- coin_a_weight: Decimal128,
- coin_b_weight: Decimal128,
+ swap_fee_rate: BigDecimal,
+ coin_a_weight: BigDecimal,
+ coin_b_weight: BigDecimal,
coin_a_metadata: Object<Metadata>,
coin_b_metadata: Object<Metadata>,
coin_a_amount: u64,
- coin_b_amount: u64,
+ coin_b_amount: u64
) acquires CoinCapabilities, Config, Pool, ModuleStore {
- let (_, timestamp) = get_block_info();
+ let (_, timestamp) = get_block_info();
let weights = Weights {
- weights_before: Weight {
- coin_a_weight,
- coin_b_weight,
- timestamp
- },
- weights_after: Weight {
- coin_a_weight,
- coin_b_weight,
- timestamp
- }
+ weights_before: Weight { coin_a_weight, coin_b_weight, timestamp },
+ weights_after: Weight { coin_a_weight, coin_b_weight, timestamp }
};
- let coin_a = coin::withdraw(creator, coin_a_metadata, coin_a_amount);
- let coin_b = coin::withdraw(creator, coin_b_metadata, coin_b_amount);
+ let coin_a = coin::withdraw(
+ creator,
+ coin_a_metadata,
+ coin_a_amount
+ );
+ let coin_b = coin::withdraw(
+ creator,
+ coin_b_metadata,
+ coin_b_amount
+ );
- let liquidity_token = create_pair(creator, name, symbol, swap_fee_rate, coin_a, coin_b, weights);
+ let liquidity_token =
+ create_pair(
+ creator,
+ name,
+ symbol,
+ swap_fee_rate,
+ coin_a,
+ coin_b,
+ weights
+ );
coin::deposit(signer::address_of(creator), liquidity_token);
}
-
-
## Function `create_lbp_pair_script`
@@ -2240,59 +2082,79 @@ permission check will be done in LP coin initialize
only LP struct owner can initialize
-public entry fun create_lbp_pair_script(creator: &signer, name: string::String, symbol: string::String, swap_fee_rate: decimal128::Decimal128, start_time: u64, coin_a_start_weight: decimal128::Decimal128, coin_b_start_weight: decimal128::Decimal128, end_time: u64, coin_a_end_weight: decimal128::Decimal128, coin_b_end_weight: decimal128::Decimal128, coin_a_metadata: object::Object<fungible_asset::Metadata>, coin_b_metadata: object::Object<fungible_asset::Metadata>, coin_a_amount: u64, coin_b_amount: u64)
+public entry fun create_lbp_pair_script(creator: &signer, name: string::String, symbol: string::String, swap_fee_rate: bigdecimal::BigDecimal, start_time: u64, coin_a_start_weight: bigdecimal::BigDecimal, coin_b_start_weight: bigdecimal::BigDecimal, end_time: u64, coin_a_end_weight: bigdecimal::BigDecimal, coin_b_end_weight: bigdecimal::BigDecimal, coin_a_metadata: object::Object<fungible_asset::Metadata>, coin_b_metadata: object::Object<fungible_asset::Metadata>, coin_a_amount: u64, coin_b_amount: u64)
-
-Implementation
+##### Implementation
public entry fun create_lbp_pair_script(
creator: &signer,
name: String,
symbol: String,
- swap_fee_rate: Decimal128,
+ swap_fee_rate: BigDecimal,
start_time: u64,
- coin_a_start_weight: Decimal128,
- coin_b_start_weight: Decimal128,
+ coin_a_start_weight: BigDecimal,
+ coin_b_start_weight: BigDecimal,
end_time: u64,
- coin_a_end_weight: Decimal128,
- coin_b_end_weight: Decimal128,
+ coin_a_end_weight: BigDecimal,
+ coin_b_end_weight: BigDecimal,
coin_a_metadata: Object<Metadata>,
coin_b_metadata: Object<Metadata>,
coin_a_amount: u64,
- coin_b_amount: u64,
+ coin_b_amount: u64
) acquires CoinCapabilities, Config, ModuleStore, Pool {
- let (_, timestamp) = get_block_info();
- assert!(start_time > timestamp, error::invalid_argument(ELBP_START_TIME));
- assert!(end_time > start_time, error::invalid_argument(EWEIGHTS_TIMESTAMP));
+ let (_, timestamp) = get_block_info();
+ assert!(
+ start_time > timestamp,
+ error::invalid_argument(ELBP_START_TIME)
+ );
+ assert!(
+ end_time > start_time,
+ error::invalid_argument(EWEIGHTS_TIMESTAMP)
+ );
let weights = Weights {
weights_before: Weight {
coin_a_weight: coin_a_start_weight,
coin_b_weight: coin_b_start_weight,
- timestamp: start_time,
+ timestamp: start_time
},
weights_after: Weight {
coin_a_weight: coin_a_end_weight,
coin_b_weight: coin_b_end_weight,
- timestamp: end_time,
+ timestamp: end_time
}
};
- let coin_a = coin::withdraw(creator, coin_a_metadata, coin_a_amount);
- let coin_b = coin::withdraw(creator, coin_b_metadata, coin_b_amount);
+ let coin_a = coin::withdraw(
+ creator,
+ coin_a_metadata,
+ coin_a_amount
+ );
+ let coin_b = coin::withdraw(
+ creator,
+ coin_b_metadata,
+ coin_b_amount
+ );
- let liquidity_token = create_pair(creator, name, symbol, swap_fee_rate, coin_a, coin_b, weights);
+ let liquidity_token =
+ create_pair(
+ creator,
+ name,
+ symbol,
+ swap_fee_rate,
+ coin_a,
+ coin_b,
+ weights
+ );
coin::deposit(signer::address_of(creator), liquidity_token);
}
-
-
## Function `update_swap_fee_rate`
@@ -2300,25 +2162,22 @@ only LP struct owner can initialize
update swap fee rate
-public entry fun update_swap_fee_rate(chain: &signer, pair: object::Object<dex::Config>, swap_fee_rate: decimal128::Decimal128)
+public entry fun update_swap_fee_rate(chain: &signer, pair: object::Object<dex::Config>, swap_fee_rate: bigdecimal::BigDecimal)
-
-Implementation
+##### Implementation
public entry fun update_swap_fee_rate(
- chain: &signer,
- pair: Object<Config>,
- swap_fee_rate: Decimal128,
+ chain: &signer, pair: Object<Config>, swap_fee_rate: BigDecimal
) acquires Config, Pool, ModuleStore {
check_chain_permission(chain);
- let config = borrow_global_mut<Config>(object::object_address(pair));
+ let config = borrow_global_mut<Config>(object::object_address(&pair));
assert!(
- decimal128::val(&swap_fee_rate) <= MAX_FEE_RATE,
+ bigdecimal::le(swap_fee_rate, max_fee_rate()),
error::invalid_argument(EOUT_OF_SWAP_FEE_RATE_RANGE)
);
@@ -2327,10 +2186,7 @@ update swap fee rate
// update PairResponse
let module_store = borrow_global_mut<ModuleStore>(@initia_std);
- let pair_response = table::borrow_mut(
- &mut module_store.pairs,
- pair_key,
- );
+ let pair_response = table::borrow_mut(&mut module_store.pairs, pair_key);
pair_response.swap_fee_rate = swap_fee_rate;
@@ -2340,16 +2196,14 @@ update swap fee rate
coin_a: pair_key.coin_a,
coin_b: pair_key.coin_b,
liquidity_token: pair_key.liquidity_token,
- swap_fee_rate,
- },
+ swap_fee_rate
+ }
);
}
-
-
## Function `provide_liquidity_script`
@@ -2362,8 +2216,7 @@ script of provide_liquidity_from_coin_store
-
-Implementation
+##### Implementation
public entry fun provide_liquidity_script(
@@ -2378,15 +2231,13 @@ script of provide_liquidity_from_coin_store
pair,
coin_a_amount_in,
coin_b_amount_in,
- min_liquidity,
+ min_liquidity
);
}
-
-
## Function `provide_liquidity_from_coin_store`
@@ -2399,8 +2250,7 @@ Provide liquidity with 0x1::coin::CoinStore coins
-
-Implementation
+##### Implementation
public fun provide_liquidity_from_coin_store(
@@ -2410,39 +2260,57 @@ Provide liquidity with 0x1::coin::CoinStore coins
coin_b_amount_in: u64,
min_liquidity: Option<u64>
): (u64, u64, u64) acquires CoinCapabilities, Config, Pool {
- let pair_addr = object::object_address(pair);
+ let pair_addr = object::object_address(&pair);
let pool = borrow_global_mut<Pool>(pair_addr);
let coin_a_amount = fungible_asset::balance(pool.coin_a_store);
let coin_b_amount = fungible_asset::balance(pool.coin_b_store);
let total_share = option::extract(&mut fungible_asset::supply(pair));
// calculate the best coin amount
- let (coin_a, coin_b) = if (total_share == 0) {
- (
- coin::withdraw(account, fungible_asset::store_metadata(pool.coin_a_store), coin_a_amount_in),
- coin::withdraw(account, fungible_asset::store_metadata(pool.coin_b_store), coin_b_amount_in),
- )
- } else {
- let coin_a_share_ratio = decimal128::from_ratio_u64(coin_a_amount_in, coin_a_amount);
- let coin_b_share_ratio = decimal128::from_ratio_u64(coin_b_amount_in, coin_b_amount);
- if (decimal128::val(&coin_a_share_ratio) > decimal128::val(&coin_b_share_ratio)) {
- coin_a_amount_in = decimal128::mul_u64(&coin_b_share_ratio, coin_a_amount);
+ let (coin_a, coin_b) =
+ if (total_share == 0) {
+ (
+ coin::withdraw(
+ account,
+ fungible_asset::store_metadata(pool.coin_a_store),
+ coin_a_amount_in
+ ),
+ coin::withdraw(
+ account,
+ fungible_asset::store_metadata(pool.coin_b_store),
+ coin_b_amount_in
+ )
+ )
} else {
- coin_b_amount_in = decimal128::mul_u64(&coin_a_share_ratio, coin_b_amount);
+ let coin_a_share_ratio =
+ bigdecimal::from_ratio_u64(coin_a_amount_in, coin_a_amount);
+ let coin_b_share_ratio =
+ bigdecimal::from_ratio_u64(coin_b_amount_in, coin_b_amount);
+ if (bigdecimal::gt(coin_a_share_ratio, coin_b_share_ratio)) {
+ coin_a_amount_in = bigdecimal::mul_by_u64_truncate(
+ coin_b_share_ratio, coin_a_amount
+ );
+ } else {
+ coin_b_amount_in = bigdecimal::mul_by_u64_truncate(
+ coin_a_share_ratio, coin_b_amount
+ );
+ };
+
+ (
+ coin::withdraw(
+ account,
+ fungible_asset::store_metadata(pool.coin_a_store),
+ coin_a_amount_in
+ ),
+ coin::withdraw(
+ account,
+ fungible_asset::store_metadata(pool.coin_b_store),
+ coin_b_amount_in
+ )
+ )
};
- (
- coin::withdraw(account, fungible_asset::store_metadata(pool.coin_a_store), coin_a_amount_in),
- coin::withdraw(account, fungible_asset::store_metadata(pool.coin_b_store), coin_b_amount_in),
- )
- };
-
- let liquidity_token = provide_liquidity(
- pair,
- coin_a,
- coin_b,
- min_liquidity,
- );
+ let liquidity_token = provide_liquidity(pair, coin_a, coin_b, min_liquidity);
let liquidity_token_amount = fungible_asset::amount(&liquidity_token);
coin::deposit(signer::address_of(account), liquidity_token);
@@ -2453,8 +2321,6 @@ Provide liquidity with 0x1::coin::CoinStore coins
-
-
## Function `withdraw_liquidity_script`
@@ -2467,8 +2333,7 @@ Withdraw liquidity with liquidity token in the token store
-
-Implementation
+##### Implementation
public entry fun withdraw_liquidity_script(
@@ -2476,17 +2341,26 @@ Withdraw liquidity with liquidity token in the token store
pair: Object<Config>,
liquidity: u64,
min_coin_a_amount: Option<u64>,
- min_coin_b_amount: Option<u64>,
+ min_coin_b_amount: Option<u64>
) acquires CoinCapabilities, Config, Pool {
- assert!(liquidity != 0, error::invalid_argument(EZERO_LIQUIDITY));
+ assert!(
+ liquidity != 0,
+ error::invalid_argument(EZERO_LIQUIDITY)
+ );
let addr = signer::address_of(account);
- let liquidity_token = coin::withdraw(account, object::convert<Config, Metadata>(pair), liquidity);
- let (coin_a, coin_b) = withdraw_liquidity(
- liquidity_token,
- min_coin_a_amount,
- min_coin_b_amount,
- );
+ let liquidity_token =
+ coin::withdraw(
+ account,
+ object::convert<Config, Metadata>(pair),
+ liquidity
+ );
+ let (coin_a, coin_b) =
+ withdraw_liquidity(
+ liquidity_token,
+ min_coin_a_amount,
+ min_coin_b_amount
+ );
coin::deposit(addr, coin_a);
coin::deposit(addr, coin_b);
@@ -2495,8 +2369,6 @@ Withdraw liquidity with liquidity token in the token store
-
-
## Function `swap_script`
@@ -2509,8 +2381,7 @@ Swap with the coin in the coin store
-
-Implementation
+##### Implementation
public entry fun swap_script(
@@ -2518,14 +2389,21 @@ Swap with the coin in the coin store
pair: Object<Config>,
offer_coin: Object<Metadata>,
offer_coin_amount: u64,
- min_return: Option<u64>,
+ min_return: Option<u64>
) acquires Config, Pool {
- let offer_coin = coin::withdraw(account, offer_coin, offer_coin_amount);
+ let offer_coin = coin::withdraw(
+ account,
+ offer_coin,
+ offer_coin_amount
+ );
let return_coin = swap(pair, offer_coin);
assert!(
- option::is_none(&min_return) || *option::borrow(&min_return) <= fungible_asset::amount(&return_coin),
- error::invalid_state(EMIN_RETURN),
+ option::is_none(&min_return)
+ || *option::borrow(&min_return) <= fungible_asset::amount(
+ &return_coin
+ ),
+ error::invalid_state(EMIN_RETURN)
);
coin::deposit(signer::address_of(account), return_coin);
@@ -2534,8 +2412,6 @@ Swap with the coin in the coin store
-
-
## Function `single_asset_provide_liquidity_script`
@@ -2548,8 +2424,7 @@ Single asset provide liquidity with token in the token store
-
-Implementation
+##### Implementation
public entry fun single_asset_provide_liquidity_script(
@@ -2561,11 +2436,8 @@ Single asset provide liquidity with token in the token store
) acquires Config, CoinCapabilities, Pool {
let addr = signer::address_of(account);
let provide_coin = coin::withdraw(account, provide_coin, amount_in);
- let liquidity_token = single_asset_provide_liquidity(
- pair,
- provide_coin,
- min_liquidity,
- );
+ let liquidity_token =
+ single_asset_provide_liquidity(pair, provide_coin, min_liquidity);
coin::deposit(addr, liquidity_token);
}
@@ -2573,8 +2445,6 @@ Single asset provide liquidity with token in the token store
-
-
## Function `withdraw_liquidity`
@@ -2588,41 +2458,51 @@ CONTRACT: not allow until LBP is ended
-
-Implementation
+##### Implementation
public fun withdraw_liquidity(
lp_token: FungibleAsset,
min_coin_a_amount: Option<u64>,
- min_coin_b_amount: Option<u64>,
+ min_coin_b_amount: Option<u64>
): (FungibleAsset, FungibleAsset) acquires CoinCapabilities, Config, Pool {
let pair_addr = coin_address(&lp_token);
let pool = borrow_global_mut<Pool>(pair_addr);
let config = borrow_global_mut<Config>(pair_addr);
- let total_share = option::extract(
- &mut fungible_asset::supply(fungible_asset::metadata_from_asset(&lp_token))
- );
+ let total_share =
+ option::extract(
+ &mut fungible_asset::supply(
+ fungible_asset::metadata_from_asset(&lp_token)
+ )
+ );
let coin_a_amount = fungible_asset::balance(pool.coin_a_store);
let given_token_amount = fungible_asset::amount(&lp_token);
let coin_b_amount = fungible_asset::balance(pool.coin_b_store);
- let given_share_ratio = decimal128::from_ratio((given_token_amount as u128), total_share);
- let coin_a_amount_out = decimal128::mul_u64(&given_share_ratio, coin_a_amount);
- let coin_b_amount_out = decimal128::mul_u64(&given_share_ratio, coin_b_amount);
+ let given_share_ratio =
+ bigdecimal::from_ratio_u128((given_token_amount as u128), total_share);
+ let coin_a_amount_out =
+ bigdecimal::mul_by_u64_truncate(given_share_ratio, coin_a_amount);
+ let coin_b_amount_out =
+ bigdecimal::mul_by_u64_truncate(given_share_ratio, coin_b_amount);
check_lbp_ended(&config.weights);
assert!(
- option::is_none(&min_coin_a_amount) || *option::borrow(&min_coin_a_amount) <= coin_a_amount_out,
- error::invalid_state(EMIN_WITHDRAW),
+ option::is_none(&min_coin_a_amount)
+ || *option::borrow(&min_coin_a_amount) <= coin_a_amount_out,
+ error::invalid_state(EMIN_WITHDRAW)
);
assert!(
- option::is_none(&min_coin_b_amount) || *option::borrow(&min_coin_b_amount) <= coin_b_amount_out,
- error::invalid_state(EMIN_WITHDRAW),
+ option::is_none(&min_coin_b_amount)
+ || *option::borrow(&min_coin_b_amount) <= coin_b_amount_out,
+ error::invalid_state(EMIN_WITHDRAW)
);
// burn liquidity token
let liquidity_token_capabilities = borrow_global<CoinCapabilities>(pair_addr);
- coin::burn(&liquidity_token_capabilities.burn_cap, lp_token);
+ coin::burn(
+ &liquidity_token_capabilities.burn_cap,
+ lp_token
+ );
// emit events
let pair_key = generate_pair_key(object::address_to_object<Config>(pair_addr));
@@ -2633,24 +2513,30 @@ CONTRACT: not allow until LBP is ended
liquidity_token: pair_addr,
coin_a_amount: coin_a_amount_out,
coin_b_amount: coin_b_amount_out,
- liquidity: given_token_amount,
- },
+ liquidity: given_token_amount
+ }
);
let pool = borrow_global_mut<Pool>(pair_addr);
// withdraw and return the coins
let pair_signer = &object::generate_signer_for_extending(&config.extend_ref);
(
- fungible_asset::withdraw(pair_signer, pool.coin_a_store, coin_a_amount_out),
- fungible_asset::withdraw(pair_signer, pool.coin_b_store, coin_b_amount_out),
+ fungible_asset::withdraw(
+ pair_signer,
+ pool.coin_a_store,
+ coin_a_amount_out
+ ),
+ fungible_asset::withdraw(
+ pair_signer,
+ pool.coin_b_store,
+ coin_b_amount_out
+ )
)
}
-
-
## Function `single_asset_provide_liquidity`
@@ -2665,82 +2551,101 @@ CONTRACT: not allow until LBP is ended
-
-Implementation
+##### Implementation
public fun single_asset_provide_liquidity(
pair: Object<Config>,
provide_coin: FungibleAsset,
- min_liquidity_amount: Option<u64>,
+ min_liquidity_amount: Option<u64>
): FungibleAsset acquires Config, CoinCapabilities, Pool {
- let pair_addr = object::object_address(pair);
+ let pair_addr = object::object_address(&pair);
let config = borrow_global<Config>(pair_addr);
check_lbp_ended(&config.weights);
// provide coin type must be one of coin a or coin b coin type
let provide_metadata = fungible_asset::metadata_from_asset(&provide_coin);
- let provide_address = object::object_address(provide_metadata);
+ let provide_address = object::object_address(&provide_metadata);
let pair_key = generate_pair_key(pair);
assert!(
provide_address == pair_key.coin_a || provide_address == pair_key.coin_b,
- error::invalid_argument(ECOIN_TYPE),
+ error::invalid_argument(ECOIN_TYPE)
);
let is_provide_a = provide_address == pair_key.coin_a;
let total_share = option::extract(&mut fungible_asset::supply(pair));
- assert!(total_share != 0, error::invalid_state(EZERO_LIQUIDITY));
+ assert!(
+ total_share != 0,
+ error::invalid_state(EZERO_LIQUIDITY)
+ );
// load values for fee and increased liquidity amount calculation
let amount_in = fungible_asset::amount(&provide_coin);
let (coin_a_weight, coin_b_weight) = get_weight(&config.weights);
let pool = borrow_global_mut<Pool>(pair_addr);
- let (normalized_weight, pool_amount_in, provide_coin_addr) = if (is_provide_a) {
- let normalized_weight = decimal128::from_ratio(
- decimal128::val(&coin_a_weight),
- decimal128::val(&coin_a_weight) + decimal128::val(&coin_b_weight)
- );
-
- let pool_amount_in = fungible_asset::balance(pool.coin_a_store);
- fungible_asset::deposit(pool.coin_a_store, provide_coin);
-
- (normalized_weight, pool_amount_in, pair_key.coin_a)
- } else {
- let normalized_weight = decimal128::from_ratio(
- decimal128::val(&coin_b_weight),
- decimal128::val(&coin_a_weight) + decimal128::val(&coin_b_weight)
- );
+ let (normalized_weight, pool_amount_in, provide_coin_addr) =
+ if (is_provide_a) {
+ let normalized_weight =
+ bigdecimal::div(
+ coin_a_weight,
+ bigdecimal::add(coin_a_weight, coin_b_weight)
+ );
+ let pool_amount_in = fungible_asset::balance(pool.coin_a_store);
+ fungible_asset::deposit(pool.coin_a_store, provide_coin);
+
+ (normalized_weight, pool_amount_in, pair_key.coin_a)
+ } else {
+ let normalized_weight =
+ bigdecimal::div(
+ coin_b_weight,
+ bigdecimal::add(coin_a_weight, coin_b_weight)
+ );
- let pool_amount_in = fungible_asset::balance(pool.coin_b_store);
- fungible_asset::deposit(pool.coin_b_store, provide_coin);
+ let pool_amount_in = fungible_asset::balance(pool.coin_b_store);
+ fungible_asset::deposit(pool.coin_b_store, provide_coin);
- (normalized_weight, pool_amount_in, pair_key.coin_b)
- };
+ (normalized_weight, pool_amount_in, pair_key.coin_b)
+ };
// CONTRACT: cannot provide more than the pool amount to prevent huge price impact
- assert!(pool_amount_in > amount_in, error::invalid_argument(EPRICE_IMPACT));
+ assert!(
+ pool_amount_in > amount_in,
+ error::invalid_argument(EPRICE_IMPACT)
+ );
// compute fee amount with the assumption that we will swap (1 - normalized_weight) of amount_in
- let adjusted_swap_amount = decimal128::mul_u64(
- &decimal128::sub(&decimal128::one(), &normalized_weight),
- amount_in
- );
- let fee_amount = decimal128::mul_u64(&config.swap_fee_rate, adjusted_swap_amount);
+ let adjusted_swap_amount =
+ bigdecimal::mul_by_u64_truncate(
+ bigdecimal::sub(
+ bigdecimal::one(),
+ normalized_weight
+ ),
+ amount_in
+ );
+ let fee_amount =
+ calculate_fee_with_minimum(
+ config.swap_fee_rate,
+ adjusted_swap_amount
+ );
// actual amount in after deducting fee amount
let adjusted_amount_in = amount_in - fee_amount;
// calculate new total share and new liquidity
- let base = decimal128::from_ratio_u64(adjusted_amount_in + pool_amount_in, pool_amount_in);
- let pool_ratio = pow(&base, &normalized_weight);
- let new_total_share = decimal128::mul_u128(&pool_ratio, total_share);
+ let base =
+ bigdecimal::from_ratio_u64(
+ adjusted_amount_in + pool_amount_in,
+ pool_amount_in
+ );
+ let pool_ratio = pow(base, normalized_weight);
+ let new_total_share = bigdecimal::mul_by_u128_truncate(pool_ratio, total_share);
let liquidity = (new_total_share - total_share as u64);
// check min liquidity assertion
assert!(
- option::is_none(&min_liquidity_amount) ||
- *option::borrow(&min_liquidity_amount) <= liquidity,
- error::invalid_state(EMIN_LIQUIDITY),
+ option::is_none(&min_liquidity_amount)
+ || *option::borrow(&min_liquidity_amount) <= liquidity,
+ error::invalid_state(EMIN_LIQUIDITY)
);
// emit events
@@ -2752,20 +2657,21 @@ CONTRACT: not allow until LBP is ended
liquidity_token: pair_addr,
provide_amount: amount_in,
fee_amount,
- liquidity,
- },
+ liquidity
+ }
);
// mint liquidity tokens to provider
let liquidity_token_capabilities = borrow_global<CoinCapabilities>(pair_addr);
- coin::mint(&liquidity_token_capabilities.mint_cap, liquidity)
+ coin::mint(
+ &liquidity_token_capabilities.mint_cap,
+ liquidity
+ )
}
-
-
## Function `swap`
@@ -2778,51 +2684,67 @@ Swap directly
-
-Implementation
+##### Implementation
public fun swap(
- pair: Object<Config>,
- offer_coin: FungibleAsset,
+ pair: Object<Config>, offer_coin: FungibleAsset
): FungibleAsset acquires Config, Pool {
let offer_amount = fungible_asset::amount(&offer_coin);
let offer_metadata = fungible_asset::metadata_from_asset(&offer_coin);
- let offer_address = object::object_address(offer_metadata);
+ let offer_address = object::object_address(&offer_metadata);
let pair_key = generate_pair_key(pair);
assert!(
offer_address == pair_key.coin_a || offer_address == pair_key.coin_b,
- error::invalid_argument(ECOIN_TYPE),
+ error::invalid_argument(ECOIN_TYPE)
);
let is_offer_a = offer_address == pair_key.coin_a;
- let (pool_a, pool_b, weight_a, weight_b, swap_fee_rate) = pool_info(pair ,true);
- let (offer_coin_addr, return_coin_addr, offer_pool, return_pool, offer_weight, return_weight) = if (is_offer_a) {
- (pair_key.coin_a, pair_key.coin_b, pool_a, pool_b, weight_a, weight_b)
- } else {
- (pair_key.coin_b, pair_key.coin_a, pool_b, pool_a, weight_b, weight_a)
- };
- let (return_amount, fee_amount) = swap_simulation(
+ let (pool_a, pool_b, weight_a, weight_b, swap_fee_rate) = pool_info(pair, true);
+ let (
+ offer_coin_addr,
+ return_coin_addr,
offer_pool,
return_pool,
offer_weight,
- return_weight,
- fungible_asset::amount(&offer_coin),
- swap_fee_rate,
- );
+ return_weight
+ ) =
+ if (is_offer_a) {
+ (pair_key.coin_a, pair_key.coin_b, pool_a, pool_b, weight_a, weight_b)
+ } else {
+ (pair_key.coin_b, pair_key.coin_a, pool_b, pool_a, weight_b, weight_a)
+ };
+ let (return_amount, fee_amount) =
+ swap_simulation(
+ offer_pool,
+ return_pool,
+ offer_weight,
+ return_weight,
+ fungible_asset::amount(&offer_coin),
+ swap_fee_rate
+ );
// apply swap result to pool
- let pair_addr = object::object_address(pair);
+ let pair_addr = object::object_address(&pair);
let pool = borrow_global_mut<Pool>(pair_addr);
let config = borrow_global<Config>(pair_addr);
let pair_signer = &object::generate_signer_for_extending(&config.extend_ref);
- let return_coin = if (is_offer_a) {
- fungible_asset::deposit(pool.coin_a_store, offer_coin);
- fungible_asset::withdraw(pair_signer, pool.coin_b_store, return_amount)
- } else {
- fungible_asset::deposit(pool.coin_b_store, offer_coin);
- fungible_asset::withdraw(pair_signer, pool.coin_a_store, return_amount)
- };
+ let return_coin =
+ if (is_offer_a) {
+ fungible_asset::deposit(pool.coin_a_store, offer_coin);
+ fungible_asset::withdraw(
+ pair_signer,
+ pool.coin_b_store,
+ return_amount
+ )
+ } else {
+ fungible_asset::deposit(pool.coin_b_store, offer_coin);
+ fungible_asset::withdraw(
+ pair_signer,
+ pool.coin_a_store,
+ return_amount
+ )
+ };
// emit events
event::emit<SwapEvent>(
@@ -2832,8 +2754,8 @@ Swap directly
liquidity_token: pair_addr,
fee_amount,
offer_amount,
- return_amount,
- },
+ return_amount
+ }
);
return_coin
@@ -2842,56 +2764,67 @@ Swap directly
-
-
## Function `create_pair`
-public fun create_pair(creator: &signer, name: string::String, symbol: string::String, swap_fee_rate: decimal128::Decimal128, coin_a: fungible_asset::FungibleAsset, coin_b: fungible_asset::FungibleAsset, weights: dex::Weights): fungible_asset::FungibleAsset
+public fun create_pair(creator: &signer, name: string::String, symbol: string::String, swap_fee_rate: bigdecimal::BigDecimal, coin_a: fungible_asset::FungibleAsset, coin_b: fungible_asset::FungibleAsset, weights: dex::Weights): fungible_asset::FungibleAsset
-
-Implementation
+##### Implementation
public fun create_pair(
creator: &signer,
name: String,
symbol: String,
- swap_fee_rate: Decimal128,
+ swap_fee_rate: BigDecimal,
coin_a: FungibleAsset,
coin_b: FungibleAsset,
- weights: Weights,
+ weights: Weights
): FungibleAsset acquires CoinCapabilities, Config, ModuleStore, Pool {
- let (mint_cap, burn_cap, freeze_cap, extend_ref) = coin::initialize_and_generate_extend_ref (
- creator,
- option::none(),
- name,
- symbol,
- 6,
- string::utf8(b""),
- string::utf8(b""),
- );
+ let (mint_cap, burn_cap, freeze_cap, extend_ref) =
+ coin::initialize_and_generate_extend_ref(
+ creator,
+ option::none(),
+ name,
+ symbol,
+ 6,
+ string::utf8(b""),
+ string::utf8(b"")
+ );
+
+ assert_weights(weights);
assert!(
- decimal128::val(&swap_fee_rate) <= MAX_FEE_RATE,
+ bigdecimal::le(swap_fee_rate, max_fee_rate()),
error::invalid_argument(EOUT_OF_SWAP_FEE_RATE_RANGE)
);
- assert!(coin_address(&coin_a) != coin_address(&coin_b), error::invalid_argument(ESAME_COIN_TYPE));
+ assert!(
+ coin_address(&coin_a) != coin_address(&coin_b),
+ error::invalid_argument(ESAME_COIN_TYPE)
+ );
let pair_signer = &object::generate_signer_for_extending(&extend_ref);
let pair_address = signer::address_of(pair_signer);
// transfer pair object's ownership to initia_std
object::transfer_raw(creator, pair_address, @initia_std);
- let coin_a_store = primary_fungible_store::create_primary_store(pair_address, fungible_asset::asset_metadata(&coin_a));
- let coin_b_store = primary_fungible_store::create_primary_store(pair_address, fungible_asset::asset_metadata(&coin_b));
+ let coin_a_store =
+ primary_fungible_store::create_primary_store(
+ pair_address,
+ fungible_asset::asset_metadata(&coin_a)
+ );
+ let coin_b_store =
+ primary_fungible_store::create_primary_store(
+ pair_address,
+ fungible_asset::asset_metadata(&coin_b)
+ );
let coin_a_addr = coin_address(&coin_a);
let coin_b_addr = coin_address(&coin_b);
@@ -2902,7 +2835,7 @@ Swap directly
move_to(
pair_signer,
- CoinCapabilities { mint_cap, freeze_cap, burn_cap },
+ CoinCapabilities { mint_cap, freeze_cap, burn_cap }
);
move_to(
@@ -2912,26 +2845,27 @@ Swap directly
// temp weights for initial provide
weights: Weights {
weights_before: Weight {
- coin_a_weight: decimal128::one(),
- coin_b_weight: decimal128::one(),
- timestamp: 0,
+ coin_a_weight: bigdecimal::one(),
+ coin_b_weight: bigdecimal::one(),
+ timestamp: 0
},
weights_after: Weight {
- coin_a_weight: decimal128::one(),
- coin_b_weight: decimal128::one(),
- timestamp: 0,
+ coin_a_weight: bigdecimal::one(),
+ coin_b_weight: bigdecimal::one(),
+ timestamp: 0
}
},
- swap_fee_rate,
+ swap_fee_rate
}
);
- let liquidity_token = provide_liquidity(
- object::address_to_object<Config>(pair_address),
- coin_a,
- coin_b,
- option::none(),
- );
+ let liquidity_token =
+ provide_liquidity(
+ object::address_to_object<Config>(pair_address),
+ coin_a,
+ coin_b,
+ option::none()
+ );
// update weights
let config = borrow_global_mut<Config>(pair_address);
@@ -2944,7 +2878,11 @@ Swap directly
// let coin_a_type = type_info::type_name<CoinA>();
// let coin_b_type = type_info::type_name<CoinB>();
// let liquidity_token_type = type_info::type_name<LiquidityToken>();
- let pair_key = PairKey { coin_a: coin_a_addr, coin_b: coin_b_addr, liquidity_token: pair_address};
+ let pair_key = PairKey {
+ coin_a: coin_a_addr,
+ coin_b: coin_b_addr,
+ liquidity_token: pair_address
+ };
// add pair to table for queries
table::add(
@@ -2955,8 +2893,8 @@ Swap directly
coin_b: coin_b_addr,
liquidity_token: pair_address,
weights,
- swap_fee_rate,
- },
+ swap_fee_rate
+ }
);
// emit create pair event
@@ -2966,8 +2904,8 @@ Swap directly
coin_b: coin_b_addr,
liquidity_token: pair_address,
weights,
- swap_fee_rate,
- },
+ swap_fee_rate
+ }
);
liquidity_token
@@ -2976,8 +2914,6 @@ Swap directly
-
-
## Function `provide_liquidity`
@@ -2991,17 +2927,16 @@ CONTRACT: not allow until LBP is ended
-
-Implementation
+##### Implementation
public fun provide_liquidity(
pair: Object<Config>,
coin_a: FungibleAsset,
coin_b: FungibleAsset,
- min_liquidity_amount: Option<u64>,
+ min_liquidity_amount: Option<u64>
): FungibleAsset acquires Config, Pool, CoinCapabilities {
- let pool_addr = object::object_address(pair);
+ let pool_addr = object::object_address(&pair);
let config = borrow_global_mut<Config>(pool_addr);
let pool = borrow_global_mut<Pool>(pool_addr);
check_lbp_ended(&config.weights);
@@ -3012,25 +2947,33 @@ CONTRACT: not allow until LBP is ended
let coin_b_amount = fungible_asset::balance(pool.coin_b_store);
let total_share = option::extract(&mut fungible_asset::supply(pair));
- let liquidity = if (total_share == 0) {
- if (coin_a_amount_in > coin_b_amount_in) {
- coin_a_amount_in
- } else {
- coin_b_amount_in
- }
- } else {
- let coin_a_share_ratio = decimal128::from_ratio_u64(coin_a_amount_in, coin_a_amount);
- let coin_b_share_ratio = decimal128::from_ratio_u64(coin_b_amount_in, coin_b_amount);
- if (decimal128::val(&coin_a_share_ratio) > decimal128::val(&coin_b_share_ratio)) {
- (decimal128::mul_u128(&coin_b_share_ratio, total_share) as u64)
+ let liquidity =
+ if (total_share == 0) {
+ if (coin_a_amount_in > coin_b_amount_in) {
+ coin_a_amount_in
+ } else {
+ coin_b_amount_in
+ }
} else {
- (decimal128::mul_u128(&coin_a_share_ratio, total_share) as u64)
- }
- };
+ let coin_a_share_ratio =
+ bigdecimal::from_ratio_u64(coin_a_amount_in, coin_a_amount);
+ let coin_b_share_ratio =
+ bigdecimal::from_ratio_u64(coin_b_amount_in, coin_b_amount);
+ if (bigdecimal::gt(coin_a_share_ratio, coin_b_share_ratio)) {
+ (
+ bigdecimal::mul_by_u128_truncate(coin_b_share_ratio, total_share) as u64
+ )
+ } else {
+ (
+ bigdecimal::mul_by_u128_truncate(coin_a_share_ratio, total_share) as u64
+ )
+ }
+ };
assert!(
- option::is_none(&min_liquidity_amount) || *option::borrow(&min_liquidity_amount) <= liquidity,
- error::invalid_state(EMIN_LIQUIDITY),
+ option::is_none(&min_liquidity_amount)
+ || *option::borrow(&min_liquidity_amount) <= liquidity,
+ error::invalid_state(EMIN_LIQUIDITY)
);
event::emit<ProvideEvent>(
@@ -3040,156 +2983,23 @@ CONTRACT: not allow until LBP is ended
liquidity_token: pool_addr,
coin_a_amount: coin_a_amount_in,
coin_b_amount: coin_b_amount_in,
- liquidity,
- },
+ liquidity
+ }
);
fungible_asset::deposit(pool.coin_a_store, coin_a);
fungible_asset::deposit(pool.coin_b_store, coin_b);
let liquidity_token_capabilities = borrow_global<CoinCapabilities>(pool_addr);
- coin::mint(&liquidity_token_capabilities.mint_cap, liquidity)
-}
-
-
-
-
-
-
-
-
-## Function `coin_address`
-
-
-
-fun coin_address(fa: &fungible_asset::FungibleAsset): address
-
-
-
-
-
-Implementation
-
-
-fun coin_address(fa: &FungibleAsset): address {
- let metadata = fungible_asset::asset_metadata(fa);
- object::object_address(metadata)
-}
-
-
-
-
-
-
-
-
-## Function `check_lbp_ended`
-
-
-
-fun check_lbp_ended(weights: &dex::Weights)
-
-
-
-
-
-Implementation
-
-
-fun check_lbp_ended(weights: &Weights) {
- let (_, timestamp) = get_block_info();
-
- assert!(timestamp >= weights.weights_after.timestamp, error::invalid_state(ELBP_NOT_ENDED))
-}
-
-
-
-
-
-
-
-
-## Function `generate_pair_key`
-
-
-
-fun generate_pair_key<T: key>(pair: object::Object<T>): dex::PairKey
-
-
-
-
-
-Implementation
-
-
-fun generate_pair_key<T: key>(pair: Object<T>): PairKey acquires Pool {
- let addr = object::object_address(pair);
- let pool = borrow_global<Pool>(addr);
- let coin_a_metadata = fungible_asset::store_metadata(pool.coin_a_store);
- let coin_b_metadata = fungible_asset::store_metadata(pool.coin_b_store);
- PairKey {
- coin_a: object::object_address(coin_a_metadata),
- coin_b: object::object_address(coin_b_metadata),
- liquidity_token: addr
- }
-}
-
-
-
-
-
-
-
-
-## Function `get_weight`
-
-return (coin_a_weight, coin_b_weight)
-
-
-fun get_weight(weights: &dex::Weights): (decimal128::Decimal128, decimal128::Decimal128)
-
-
-
-
-
-Implementation
-
-
-fun get_weight(weights: &Weights): (Decimal128, Decimal128) {
- let (_, timestamp) = get_block_info();
- if (timestamp <= weights.weights_before.timestamp) {
- (weights.weights_before.coin_a_weight, weights.weights_before.coin_b_weight)
- } else if (timestamp < weights.weights_after.timestamp) {
- let interval = (weights.weights_after.timestamp - weights.weights_before.timestamp as u128);
- let time_diff_after = (weights.weights_after.timestamp - timestamp as u128);
- let time_diff_before = (timestamp - weights.weights_before.timestamp as u128);
-
- // when timestamp_before < timestamp < timestamp_after
- // weight = a * timestamp + b
- // m = (a * timestamp_before + b) * (timestamp_after - timestamp)
- // = a * t_b * t_a - a * t_b * t + b * t_a - b * t
- // n = (a * timestamp_after + b) * (timestamp - timestamp_before)
- // = a * t_a * t - a * t_a * t_b + b * t - b * t_b
- // l = m + n = a * t * (t_a - t_b) + b * (t_a - t_b)
- // weight = l / (t_a - t_b)
- let coin_a_m = decimal128::new(decimal128::val(&weights.weights_after.coin_a_weight) * time_diff_before);
- let coin_a_n = decimal128::new(decimal128::val(&weights.weights_before.coin_a_weight) * time_diff_after);
- let coin_a_l = decimal128::add(&coin_a_m, &coin_a_n);
-
- let coin_b_m = decimal128::new(decimal128::val(&weights.weights_after.coin_b_weight) * time_diff_before);
- let coin_b_n = decimal128::new(decimal128::val(&weights.weights_before.coin_b_weight) * time_diff_after);
- let coin_b_l = decimal128::add(&coin_b_m, &coin_b_n);
- (decimal128::div(&coin_a_l, interval), decimal128::div(&coin_b_l, interval))
- } else {
- (weights.weights_after.coin_a_weight, weights.weights_after.coin_b_weight)
- }
+ coin::mint(
+ &liquidity_token_capabilities.mint_cap,
+ liquidity
+ )
}
-
-
## Function `pool_info`
@@ -3197,22 +3007,26 @@ return (coin_a_weight, coin_b_weight)
get all pool info at once (a_amount, b_amount, a_weight, b_weight, fee_rate)
-public fun pool_info(pair: object::Object<dex::Config>, lbp_assertion: bool): (u64, u64, decimal128::Decimal128, decimal128::Decimal128, decimal128::Decimal128)
+public fun pool_info(pair: object::Object<dex::Config>, lbp_assertion: bool): (u64, u64, bigdecimal::BigDecimal, bigdecimal::BigDecimal, bigdecimal::BigDecimal)
-
-Implementation
+##### Implementation
-public fun pool_info(pair: Object<Config>, lbp_assertion: bool): (u64, u64, Decimal128, Decimal128, Decimal128) acquires Config, Pool {
- let pair_addr = object::object_address(pair);
+public fun pool_info(
+ pair: Object<Config>, lbp_assertion: bool
+): (u64, u64, BigDecimal, BigDecimal, BigDecimal) acquires Config, Pool {
+ let pair_addr = object::object_address(&pair);
let config = borrow_global<Config>(pair_addr);
if (lbp_assertion) {
// assert LBP start time
- let (_, timestamp) = get_block_info();
- assert!(timestamp >= config.weights.weights_before.timestamp, error::invalid_state(ELBP_NOT_STARTED));
+ let (_, timestamp) = get_block_info();
+ assert!(
+ timestamp >= config.weights.weights_before.timestamp,
+ error::invalid_state(ELBP_NOT_STARTED)
+ );
};
let pool = borrow_global<Pool>(pair_addr);
@@ -3223,15 +3037,13 @@ get all pool info at once (a_amount, b_amount, a_weight, b_weight, fee_rate)
fungible_asset::balance(pool.coin_b_store),
coin_a_weight,
coin_b_weight,
- config.swap_fee_rate,
+ config.swap_fee_rate
)
}
-
-
## Function `swap_simulation`
@@ -3241,69 +3053,84 @@ https://balancer.fi/whitepaper.pdf (15)
return (return_amount, fee_amount)
-public fun swap_simulation(pool_amount_in: u64, pool_amount_out: u64, weight_in: decimal128::Decimal128, weight_out: decimal128::Decimal128, amount_in: u64, swap_fee_rate: decimal128::Decimal128): (u64, u64)
+public fun swap_simulation(pool_amount_in: u64, pool_amount_out: u64, weight_in: bigdecimal::BigDecimal, weight_out: bigdecimal::BigDecimal, amount_in: u64, swap_fee_rate: bigdecimal::BigDecimal): (u64, u64)
-
-Implementation
+##### Implementation
public fun swap_simulation(
pool_amount_in: u64,
pool_amount_out: u64,
- weight_in: Decimal128,
- weight_out: Decimal128,
+ weight_in: BigDecimal,
+ weight_out: BigDecimal,
amount_in: u64,
- swap_fee_rate: Decimal128,
+ swap_fee_rate: BigDecimal
): (u64, u64) {
- let one = decimal128::one();
- let exp = decimal128::from_ratio(decimal128::val(&weight_in), decimal128::val(&weight_out));
- let fee_amount = decimal128::mul_u64(&swap_fee_rate, amount_in);
+ assert!(
+ amount_in > 0,
+ error::invalid_argument(EZERO_AMOUNT_IN)
+ );
+
+ let one = bigdecimal::one();
+ let exp = bigdecimal::div(weight_in, weight_out);
+
+ let fee_amount = calculate_fee_with_minimum(swap_fee_rate, amount_in);
let adjusted_amount_in = amount_in - fee_amount;
- let base = decimal128::from_ratio_u64(pool_amount_in, pool_amount_in + adjusted_amount_in);
- let sub_amount = pow(&base, &exp);
- (decimal128::mul_u64(&decimal128::sub(&one, &sub_amount), pool_amount_out), fee_amount)
+ let base =
+ bigdecimal::from_ratio_u64(
+ pool_amount_in,
+ pool_amount_in + adjusted_amount_in
+ );
+ let sub_amount = pow(base, exp);
+ (
+ bigdecimal::mul_by_u64_truncate(
+ bigdecimal::sub(one, sub_amount),
+ pool_amount_out
+ ),
+ fee_amount
+ )
}
-
-
## Function `swap_simulation_given_out`
-public fun swap_simulation_given_out(pool_amount_in: u64, pool_amount_out: u64, weight_in: decimal128::Decimal128, weight_out: decimal128::Decimal128, amount_out: u64, swap_fee_rate: decimal128::Decimal128): (u64, u64)
+public fun swap_simulation_given_out(pool_amount_in: u64, pool_amount_out: u64, weight_in: bigdecimal::BigDecimal, weight_out: bigdecimal::BigDecimal, amount_out: u64, swap_fee_rate: bigdecimal::BigDecimal): (u64, u64)
-
-Implementation
+##### Implementation
public fun swap_simulation_given_out(
pool_amount_in: u64,
pool_amount_out: u64,
- weight_in: Decimal128,
- weight_out: Decimal128,
+ weight_in: BigDecimal,
+ weight_out: BigDecimal,
amount_out: u64,
- swap_fee_rate: Decimal128,
+ swap_fee_rate: BigDecimal
): (u64, u64) {
- let one = decimal128::one();
- let exp = decimal128::from_ratio(decimal128::val(&weight_out), decimal128::val(&weight_in));
- let base = decimal128::from_ratio_u64(pool_amount_out, pool_amount_out - amount_out);
- let base_exp = pow(&base, &exp);
- let adjusted_amount_in = decimal128::val(&decimal128::sub(&base_exp, &one)) * (pool_amount_in as u128) ;
- let sub_one_fee = decimal128::sub(&one, &swap_fee_rate);
-
- let amount_in = ( adjusted_amount_in / decimal128::val(&sub_one_fee) as u64);
- let fee_amount = decimal128::mul_u64(&swap_fee_rate, amount_in);
+ let one = bigdecimal::one();
+ let exp = bigdecimal::div(weight_out, weight_in);
+ let base = bigdecimal::from_ratio_u64(
+ pool_amount_out, pool_amount_out - amount_out
+ );
+ let base_exp = pow(base, exp);
+ let adjusted_amount_in =
+ bigdecimal::mul_by_u64(bigdecimal::sub(base_exp, one), pool_amount_in);
+ let sub_one_fee = bigdecimal::sub(one, swap_fee_rate);
+ let amount_in =
+ bigdecimal::truncate_u64(bigdecimal::div(adjusted_amount_in, sub_one_fee));
+ let fee_amount = calculate_fee_with_minimum(swap_fee_rate, amount_in);
(amount_in, fee_amount)
}
@@ -3311,8 +3138,6 @@ return (return_amount, fee_amount)
-
-
## Function `pool_metadata`
@@ -3324,153 +3149,17 @@ return (return_amount, fee_amount)
-
-Implementation
+##### Implementation
-public fun pool_metadata(pair: Object<Config>): (Object<Metadata>, Object<Metadata>) acquires Pool {
- let pair_addr = object::object_address(pair);
+public fun pool_metadata(
+ pair: Object<Config>
+): (Object<Metadata>, Object<Metadata>) acquires Pool {
+ let pair_addr = object::object_address(&pair);
let pool = borrow_global<Pool>(pair_addr);
- (fungible_asset::store_metadata(pool.coin_a_store), fungible_asset::store_metadata(pool.coin_b_store))
-}
-
-
-
-
-
-
-
-
-## Function `pow`
-
-a^x = 1 + sigma[(k^n)/n!]
-k = x * ln(a)
-
-
-fun pow(base: &decimal128::Decimal128, exp: &decimal128::Decimal128): decimal128::Decimal128
-
-
-
-
-
-Implementation
-
-
-fun pow(base: &Decimal128, exp: &Decimal128): Decimal128 {
- assert!(
- decimal128::val(base) != 0 && decimal128::val(base) < 2000000000000000000,
- error::invalid_argument(EOUT_OF_BASE_RANGE),
- );
-
- let res = decimal128::one();
- let (ln_a, neg) = ln(base);
- let k = mul_decimal128s(&ln_a, exp);
- let comp = k;
- let index = 1;
- let subs: vector<Decimal128> = vector[];
- while (decimal128::val(&comp) > PRECISION) {
- if (index & 1 == 1 && neg) {
- vector::push_back(&mut subs, comp)
- } else {
- res = decimal128::add(&res, &comp)
- };
-
- comp = decimal128::div(&mul_decimal128s(&comp, &k), index + 1);
- index = index + 1;
- };
-
- let index = 0;
- while (index < vector::length(&subs)) {
- let comp = vector::borrow(&subs, index);
- res = decimal128::sub(&res, comp);
- index = index + 1;
- };
-
- res
-}
-
-
-
-
-
-
-
-
-## Function `ln`
-
-ln(1 + a) = sigma[(-1) ^ (n + 1) * (a ^ n / n)]
-https://en.wikipedia.org/wiki/Taylor_series#Natural_logarithm
-
-
-fun ln(num: &decimal128::Decimal128): (decimal128::Decimal128, bool)
-
-
-
-
-
-Implementation
-
-
-fun ln(num: &Decimal128): (Decimal128, bool) {
- let one = decimal128::val(&decimal128::one());
- let num_val = decimal128::val(num);
- let (a, a_neg) = if (num_val >= one) {
- (decimal128::sub(num, &decimal128::one()), false)
- } else {
- (decimal128::sub(&decimal128::one(), num), true)
- };
-
- let res = decimal128::zero();
- let comp = a;
- let index = 1;
-
- while (decimal128::val(&comp) > PRECISION) {
- if (index & 1 == 0 && !a_neg) {
- res = decimal128::sub(&res, &comp);
- } else {
- res = decimal128::add(&res, &comp);
- };
-
- // comp(old) = a ^ n / n
- // comp(new) = comp(old) * a * n / (n + 1) = a ^ (n + 1) / (n + 1)
- comp = decimal128::div(
- &decimal128::new(decimal128::val(&mul_decimal128s(&comp, &a)) * index), // comp * a * index
- index + 1,
- );
-
- index = index + 1;
- };
-
- (res, a_neg)
-}
-
-
-
-
-
-
-
-
-## Function `mul_decimal128s`
-
-
-
-fun mul_decimal128s(decimal128_0: &decimal128::Decimal128, decimal128_1: &decimal128::Decimal128): decimal128::Decimal128
-
-
-
-
-
-Implementation
-
-
-fun mul_decimal128s(decimal128_0: &Decimal128, decimal128_1: &Decimal128): Decimal128 {
- let one = (decimal128::val(&decimal128::one()) as u256);
- let val_mul = (decimal128::val(decimal128_0) as u256) * (decimal128::val(decimal128_1) as u256);
- decimal128::new((val_mul / one as u128))
+ (
+ fungible_asset::store_metadata(pool.coin_a_store),
+ fungible_asset::store_metadata(pool.coin_b_store)
+ )
}
-
-
-
-
diff --git a/initia_stdlib/doc/dispatchable_fungible_asset.md b/initia_stdlib/doc/dispatchable_fungible_asset.md
new file mode 100644
index 0000000..d5d9ac2
--- /dev/null
+++ b/initia_stdlib/doc/dispatchable_fungible_asset.md
@@ -0,0 +1,382 @@
+
+
+
+# Module `0x1::dispatchable_fungible_asset`
+
+This defines the fungible asset module that can issue fungible asset of any Metadata
object. The
+metadata object can be any object that equipped with Metadata
resource.
+
+The dispatchable_fungible_asset wraps the existing fungible_asset module and adds the ability for token issuer
+to customize the logic for withdraw and deposit operations. For example:
+
+- Deflation token: a fixed percentage of token will be destructed upon transfer.
+- Transfer allowlist: token can only be transfered to addresses in the allow list.
+- Predicated transfer: transfer can only happen when some certain predicate has been met.
+- Loyalty token: a fixed loyalty will be paid to a designated address when a fungible asset transfer happens
+
+The api listed here intended to be an in-place replacement for defi applications that uses fungible_asset api directly
+and is safe for non-dispatchable (aka vanilla) fungible assets as well.
+
+See AIP-73 for further discussion
+
+
+- [Resource `TransferRefStore`](#0x1_dispatchable_fungible_asset_TransferRefStore)
+- [Constants](#@Constants_0)
+- [Function `register_dispatch_functions`](#0x1_dispatchable_fungible_asset_register_dispatch_functions)
+- [Function `register_derive_supply_dispatch_function`](#0x1_dispatchable_fungible_asset_register_derive_supply_dispatch_function)
+- [Function `withdraw`](#0x1_dispatchable_fungible_asset_withdraw)
+- [Function `deposit`](#0x1_dispatchable_fungible_asset_deposit)
+- [Function `transfer`](#0x1_dispatchable_fungible_asset_transfer)
+- [Function `transfer_assert_minimum_deposit`](#0x1_dispatchable_fungible_asset_transfer_assert_minimum_deposit)
+- [Function `derived_balance`](#0x1_dispatchable_fungible_asset_derived_balance)
+- [Function `derived_supply`](#0x1_dispatchable_fungible_asset_derived_supply)
+
+
+use 0x1::error;
+use 0x1::function_info;
+use 0x1::fungible_asset;
+use 0x1::object;
+use 0x1::option;
+
+
+
+
+
+
+## Resource `TransferRefStore`
+
+
+
+struct TransferRefStore has key
+
+
+
+
+##### Fields
+
+
+
+-
+
transfer_ref: fungible_asset::TransferRef
+
+-
+
+
+
+
+
+
+
+## Constants
+
+
+
+
+Feature is not activated yet on the network.
+
+
+const ENOT_ACTIVATED: u64 = 3;
+
+
+
+
+
+
+Recipient is not getting the guaranteed value;
+
+
+const EAMOUNT_MISMATCH: u64 = 2;
+
+
+
+
+
+
+Dispatch target is not loaded.
+
+
+const ENOT_LOADED: u64 = 4;
+
+
+
+
+
+
+TransferRefStore doesn't exist on the fungible asset type.
+
+
+const ESTORE_NOT_FOUND: u64 = 1;
+
+
+
+
+
+
+## Function `register_dispatch_functions`
+
+
+
+public fun register_dispatch_functions(constructor_ref: &object::ConstructorRef, withdraw_function: option::Option<function_info::FunctionInfo>, deposit_function: option::Option<function_info::FunctionInfo>, derived_balance_function: option::Option<function_info::FunctionInfo>)
+
+
+
+
+##### Implementation
+
+
+public fun register_dispatch_functions(
+ constructor_ref: &ConstructorRef,
+ withdraw_function: Option<FunctionInfo>,
+ deposit_function: Option<FunctionInfo>,
+ derived_balance_function: Option<FunctionInfo>
+) {
+ fungible_asset::register_dispatch_functions(
+ constructor_ref,
+ withdraw_function,
+ deposit_function,
+ derived_balance_function
+ );
+ let store_obj = &object::generate_signer(constructor_ref);
+ move_to<TransferRefStore>(
+ store_obj,
+ TransferRefStore {
+ transfer_ref: fungible_asset::generate_transfer_ref(constructor_ref)
+ }
+ );
+}
+
+
+
+
+
+
+## Function `register_derive_supply_dispatch_function`
+
+
+
+public fun register_derive_supply_dispatch_function(constructor_ref: &object::ConstructorRef, dispatch_function: option::Option<function_info::FunctionInfo>)
+
+
+
+
+##### Implementation
+
+
+public fun register_derive_supply_dispatch_function(
+ constructor_ref: &ConstructorRef, dispatch_function: Option<FunctionInfo>
+) {
+ fungible_asset::register_derive_supply_dispatch_function(
+ constructor_ref, dispatch_function
+ );
+}
+
+
+
+
+
+
+## Function `withdraw`
+
+Withdraw amount
of the fungible asset from store
by the owner.
+
+The semantics of deposit will be governed by the function specified in DispatchFunctionStore.
+
+
+public fun withdraw<T: key>(owner: &signer, store: object::Object<T>, amount: u64): fungible_asset::FungibleAsset
+
+
+
+
+##### Implementation
+
+
+public fun withdraw<T: key>(
+ owner: &signer, store: Object<T>, amount: u64
+): FungibleAsset acquires TransferRefStore {
+ fungible_asset::withdraw_sanity_check(owner, store, false);
+ let func_opt = fungible_asset::withdraw_dispatch_function(store);
+ if (option::is_some(&func_opt)) {
+ let start_balance = fungible_asset::balance(store);
+ let func = option::borrow(&func_opt);
+ function_info::load_module_from_function(func);
+ let fa = dispatchable_withdraw(
+ store,
+ amount,
+ borrow_transfer_ref(store),
+ func
+ );
+ let end_balance = fungible_asset::balance(store);
+ assert!(
+ amount <= start_balance - end_balance,
+ error::aborted(EAMOUNT_MISMATCH)
+ );
+ fa
+ } else {
+ fungible_asset::withdraw_internal(object::object_address(&store), amount)
+ }
+}
+
+
+
+
+
+
+## Function `deposit`
+
+Deposit amount
of the fungible asset to store
.
+
+The semantics of deposit will be governed by the function specified in DispatchFunctionStore.
+
+
+public fun deposit<T: key>(store: object::Object<T>, fa: fungible_asset::FungibleAsset)
+
+
+
+
+##### Implementation
+
+
+public fun deposit<T: key>(store: Object<T>, fa: FungibleAsset) acquires TransferRefStore {
+ fungible_asset::deposit_sanity_check(store, false);
+ let func_opt = fungible_asset::deposit_dispatch_function(store);
+ if (option::is_some(&func_opt)) {
+ let func = option::borrow(&func_opt);
+ function_info::load_module_from_function(func);
+ dispatchable_deposit(
+ store,
+ fa,
+ borrow_transfer_ref(store),
+ func
+ )
+ } else {
+ fungible_asset::deposit_internal(object::object_address(&store), fa)
+ }
+}
+
+
+
+
+
+
+## Function `transfer`
+
+Transfer an amount
of fungible asset from from_store
, which should be owned by sender
, to receiver
.
+Note: it does not move the underlying object.
+
+
+public entry fun transfer<T: key>(sender: &signer, from: object::Object<T>, to: object::Object<T>, amount: u64)
+
+
+
+
+##### Implementation
+
+
+public entry fun transfer<T: key>(
+ sender: &signer,
+ from: Object<T>,
+ to: Object<T>,
+ amount: u64
+) acquires TransferRefStore {
+ let fa = withdraw(sender, from, amount);
+ deposit(to, fa);
+}
+
+
+
+
+
+
+## Function `transfer_assert_minimum_deposit`
+
+Transfer an amount
of fungible asset from from_store
, which should be owned by sender
, to receiver
.
+The recipient is guranteed to receive asset greater than the expected amount.
+Note: it does not move the underlying object.
+
+
+public entry fun transfer_assert_minimum_deposit<T: key>(sender: &signer, from: object::Object<T>, to: object::Object<T>, amount: u64, expected: u64)
+
+
+
+
+##### Implementation
+
+
+public entry fun transfer_assert_minimum_deposit<T: key>(
+ sender: &signer,
+ from: Object<T>,
+ to: Object<T>,
+ amount: u64,
+ expected: u64
+) acquires TransferRefStore {
+ let start = fungible_asset::balance(to);
+ let fa = withdraw(sender, from, amount);
+ deposit(to, fa);
+ let end = fungible_asset::balance(to);
+ assert!(end - start >= expected, error::aborted(EAMOUNT_MISMATCH));
+}
+
+
+
+
+
+
+## Function `derived_balance`
+
+Get the derived value of store using the overloaded hook.
+
+The semantics of value will be governed by the function specified in DispatchFunctionStore.
+
+
+#[view]
+public fun derived_balance<T: key>(store: object::Object<T>): u64
+
+
+
+
+##### Implementation
+
+
+public fun derived_balance<T: key>(store: Object<T>): u64 {
+ let func_opt = fungible_asset::derived_balance_dispatch_function(store);
+ if (option::is_some(&func_opt)) {
+ let func = option::borrow(&func_opt);
+ function_info::load_module_from_function(func);
+ dispatchable_derived_balance(store, func)
+ } else {
+ fungible_asset::balance(store)
+ }
+}
+
+
+
+
+
+
+## Function `derived_supply`
+
+Get the derived supply of the fungible asset using the overloaded hook.
+
+The semantics of supply will be governed by the function specified in DeriveSupplyDispatch.
+
+
+#[view]
+public fun derived_supply<T: key>(metadata: object::Object<T>): option::Option<u128>
+
+
+
+
+##### Implementation
+
+
+public fun derived_supply<T: key>(metadata: Object<T>): Option<u128> {
+ let func_opt = fungible_asset::derived_supply_dispatch_function(metadata);
+ if (option::is_some(&func_opt)) {
+ let func = option::borrow(&func_opt);
+ function_info::load_module_from_function(func);
+ dispatchable_derived_supply(metadata, func)
+ } else {
+ fungible_asset::supply(metadata)
+ }
+}
+
diff --git a/initia_stdlib/doc/ed25519.md b/initia_stdlib/doc/ed25519.md
index 4f8891a..21787aa 100644
--- a/initia_stdlib/doc/ed25519.md
+++ b/initia_stdlib/doc/ed25519.md
@@ -17,8 +17,6 @@ Contains functions for:
- [Function `signature_to_bytes`](#0x1_ed25519_signature_to_bytes)
- [Function `verify`](#0x1_ed25519_verify)
- [Function `batch_verify`](#0x1_ed25519_batch_verify)
-- [Function `verify_internal`](#0x1_ed25519_verify_internal)
-- [Function `batch_verify_internal`](#0x1_ed25519_batch_verify_internal)
use 0x1::error;
@@ -38,8 +36,7 @@ A Ed25519 public key
-
-Fields
+##### Fields
@@ -52,8 +49,6 @@ A Ed25519 public key
-
-
## Struct `Signature`
@@ -66,8 +61,7 @@ A Ed25519 signature that can be verified via verify_internal
or
-Fields
+##### Fields
@@ -80,13 +74,21 @@ A Ed25519 signature that can be verified via verify_internal
or
-
-
## Constants
+
+
+The number of messages, public keys, and signatures do not match.
+
+
+const E_UNMATCHED_ARGS_LENGTH: u64 = 3;
+
+
+
+
Wrong number of bytes were given as input when deserializing an Ed25519 public key.
@@ -139,14 +141,13 @@ Contructs an PublicKey struct, given 32-byte representation.
-
-Implementation
+##### Implementation
public fun public_key_from_bytes(bytes: vector<u8>): PublicKey {
assert!(
std::vector::length(&bytes) == PUBLIC_KEY_SIZE,
- std::error::invalid_argument(PUBLIC_KEY_SIZE),
+ std::error::invalid_argument(PUBLIC_KEY_SIZE)
);
PublicKey { bytes }
}
@@ -154,8 +155,6 @@ Contructs an PublicKey struct, given 32-byte representation.
-
-
## Function `signature_from_bytes`
@@ -168,20 +167,20 @@ Constructs an Signature struct from the given 64 bytes.
-
-Implementation
+##### Implementation
public fun signature_from_bytes(bytes: vector<u8>): Signature {
- assert!(std::vector::length(&bytes) == SIGNATURE_SIZE, std::error::invalid_argument(E_WRONG_SIGNATURE_SIZE));
+ assert!(
+ std::vector::length(&bytes) == SIGNATURE_SIZE,
+ std::error::invalid_argument(E_WRONG_SIGNATURE_SIZE)
+ );
Signature { bytes }
}
-
-
## Function `public_key_to_bytes`
@@ -194,8 +193,7 @@ Serializes an PublicKey struct to bytes.
-
-Implementation
+##### Implementation
public fun public_key_to_bytes(pk: &PublicKey): vector<u8> {
@@ -205,8 +203,6 @@ Serializes an PublicKey struct to bytes.
-
-
## Function `signature_to_bytes`
@@ -219,8 +215,7 @@ Serializes an Signature struct to bytes.
-
-Implementation
+##### Implementation
public fun signature_to_bytes(sig: &Signature): vector<u8> {
@@ -230,8 +225,6 @@ Serializes an Signature struct to bytes.
-
-
## Function `verify`
@@ -244,23 +237,22 @@ Verifies a Ed25519 signature
under an public_key
on th
-
-Implementation
+##### Implementation
public fun verify(
- message: vector<u8>,
- public_key: &PublicKey,
- signature: &Signature,
+ message: vector<u8>, public_key: &PublicKey, signature: &Signature
): bool {
- verify_internal(message, public_key.bytes, signature.bytes)
+ verify_internal(
+ message,
+ public_key.bytes,
+ signature.bytes
+ )
}
-
-
## Function `batch_verify`
@@ -288,67 +280,39 @@ case.
-
-Implementation
+##### Implementation
public fun batch_verify(
messages: vector<vector<u8>>,
public_keys: vector<PublicKey>,
- signatures: vector<Signature>,
+ signatures: vector<Signature>
): bool {
+ let message_length = std::vector::length(&messages);
+ let public_key_length = std::vector::length(&public_keys);
+ let signature_length = std::vector::length(&signatures);
+
+ if (message_length == 1) {
+ assert!(
+ public_key_length == signature_length,
+ std::error::invalid_argument(E_UNMATCHED_ARGS_LENGTH)
+ );
+ if (public_key_length == 0) return true;
+ } else if (public_key_length == 1) {
+ assert!(
+ message_length == signature_length,
+ std::error::invalid_argument(E_UNMATCHED_ARGS_LENGTH)
+ );
+ if (message_length == 0) return true;
+ } else {
+ assert!(
+ message_length == public_key_length
+ && public_key_length == signature_length,
+ std::error::invalid_argument(E_UNMATCHED_ARGS_LENGTH)
+ );
+ if (message_length == 0) return true;
+ };
+
batch_verify_internal(messages, public_keys, signatures)
}
-
-
-
-
-
-
-
-## Function `verify_internal`
-
-
-
-fun verify_internal(message: vector<u8>, public_key: vector<u8>, signature: vector<u8>): bool
-
-
-
-
-
-Implementation
-
-
-native fun verify_internal(message: vector<u8>, public_key: vector<u8>, signature: vector<u8>): bool;
-
-
-
-
-
-
-
-
-## Function `batch_verify_internal`
-
-
-
-fun batch_verify_internal(messages: vector<vector<u8>>, public_keys: vector<ed25519::PublicKey>, signatures: vector<ed25519::Signature>): bool
-
-
-
-
-
-Implementation
-
-
-native fun batch_verify_internal(
- messages: vector<vector<u8>>,
- public_keys: vector<PublicKey>,
- signatures: vector<Signature>
-): bool;
-
-
-
-
-
diff --git a/initia_stdlib/doc/event.md b/initia_stdlib/doc/event.md
index b46a429..caafc44 100644
--- a/initia_stdlib/doc/event.md
+++ b/initia_stdlib/doc/event.md
@@ -6,7 +6,6 @@
- [Function `emit`](#0x1_event_emit)
-- [Function `write_module_event_to_store`](#0x1_event_write_module_event_to_store)
@@ -20,43 +19,15 @@
Emit an event with payload msg
by using handle_ref
's key and counter.
-public fun emit<T: drop, store>(msg: T)
+public fun emit<T: drop>(msg: T)
-
-Implementation
+##### Implementation
-public fun emit<T: store + drop>(msg: T) {
- write_module_event_to_store<T>(msg);
+public fun emit<T: drop>(msg: T) {
+ emit_event<T>(&msg);
}
-
-
-
-
-
-
-
-## Function `write_module_event_to_store`
-
-Log msg
with the event stream identified by T
-
-
-fun write_module_event_to_store<T: drop, store>(msg: T)
-
-
-
-
-
-Implementation
-
-
-native fun write_module_event_to_store<T: drop + store>(msg: T);
-
-
-
-
-
diff --git a/initia_stdlib/doc/fixed_point64.md b/initia_stdlib/doc/fixed_point64.md
index b355b2e..9da9a36 100644
--- a/initia_stdlib/doc/fixed_point64.md
+++ b/initia_stdlib/doc/fixed_point64.md
@@ -9,19 +9,39 @@ a 64-bit fractional part.
- [Struct `FixedPoint64`](#0x1_fixed_point64_FixedPoint64)
- [Constants](#@Constants_0)
+- [Function `one`](#0x1_fixed_point64_one)
+- [Function `zero`](#0x1_fixed_point64_zero)
+- [Function `rev`](#0x1_fixed_point64_rev)
+- [Function `sub`](#0x1_fixed_point64_sub)
+- [Function `sub_u64`](#0x1_fixed_point64_sub_u64)
+- [Function `sub_u128`](#0x1_fixed_point64_sub_u128)
+- [Function `add`](#0x1_fixed_point64_add)
+- [Function `add_u64`](#0x1_fixed_point64_add_u64)
+- [Function `add_u128`](#0x1_fixed_point64_add_u128)
+- [Function `multiply`](#0x1_fixed_point64_multiply)
+- [Function `multiply_u64`](#0x1_fixed_point64_multiply_u64)
- [Function `multiply_u128`](#0x1_fixed_point64_multiply_u128)
+- [Function `divide`](#0x1_fixed_point64_divide)
+- [Function `divide_u64`](#0x1_fixed_point64_divide_u64)
+- [Function `divide_by_u64`](#0x1_fixed_point64_divide_by_u64)
- [Function `divide_u128`](#0x1_fixed_point64_divide_u128)
+- [Function `divide_by_u128`](#0x1_fixed_point64_divide_by_u128)
- [Function `create_from_rational`](#0x1_fixed_point64_create_from_rational)
- [Function `create_from_raw_value`](#0x1_fixed_point64_create_from_raw_value)
- [Function `get_raw_value`](#0x1_fixed_point64_get_raw_value)
- [Function `is_zero`](#0x1_fixed_point64_is_zero)
- [Function `min`](#0x1_fixed_point64_min)
- [Function `max`](#0x1_fixed_point64_max)
+- [Function `less_or_equal`](#0x1_fixed_point64_less_or_equal)
+- [Function `less`](#0x1_fixed_point64_less)
+- [Function `greater_or_equal`](#0x1_fixed_point64_greater_or_equal)
+- [Function `greater`](#0x1_fixed_point64_greater)
+- [Function `equal`](#0x1_fixed_point64_equal)
+- [Function `almost_equal`](#0x1_fixed_point64_almost_equal)
- [Function `create_from_u128`](#0x1_fixed_point64_create_from_u128)
- [Function `floor`](#0x1_fixed_point64_floor)
- [Function `ceil`](#0x1_fixed_point64_ceil)
- [Function `round`](#0x1_fixed_point64_round)
-- [Module Specification](#@Module_Specification_1)
@@ -48,8 +68,7 @@ decimal.
-
-Fields
+##### Fields
@@ -62,13 +81,20 @@ decimal.
-
-
## Constants
+
+
+
+
+const MAX_U64: u128 = 18446744073709551615;
+
+
+
+
@@ -78,6 +104,16 @@ decimal.
+
+
+A division by zero was encountered
+
+
+const EDIVISION_BY_ZERO: u64 = 65540;
+
+
+
+
The denominator provided was zero
@@ -98,22 +134,22 @@ The quotient value would be too large to be held in a u128
-
+
-A division by zero was encountered
+The multiplied value would be too large to be held in a u128
-const EDIVISION_BY_ZERO: u64 = 65540;
+const EMULTIPLICATION: u64 = 131075;
-
+
-The multiplied value would be too large to be held in a u128
+Abort code on calculation result is negative.
-const EMULTIPLICATION: u64 = 131075;
+const ENEGATIVE_RESULT: u64 = 65542;
@@ -128,6 +164,259 @@ The computed ratio when converting to a
+
+## Function `one`
+
+
+
+public fun one(): fixed_point64::FixedPoint64
+
+
+
+
+##### Implementation
+
+
+public fun one(): FixedPoint64 {
+ create_from_raw_value(1 << 64)
+}
+
+
+
+
+
+
+## Function `zero`
+
+
+
+public fun zero(): fixed_point64::FixedPoint64
+
+
+
+
+##### Implementation
+
+
+public fun zero(): FixedPoint64 {
+ create_from_raw_value(0)
+}
+
+
+
+
+
+
+## Function `rev`
+
+
+
+public fun rev(self: fixed_point64::FixedPoint64): fixed_point64::FixedPoint64
+
+
+
+
+##### Implementation
+
+
+public fun rev(self: FixedPoint64): FixedPoint64 {
+ create_from_raw_value(((1u256 << 128) / (get_raw_value(self) as u256) as u128))
+}
+
+
+
+
+
+
+## Function `sub`
+
+Returns self - y. self must be not less than y.
+
+
+public fun sub(self: fixed_point64::FixedPoint64, y: fixed_point64::FixedPoint64): fixed_point64::FixedPoint64
+
+
+
+
+##### Implementation
+
+
+public fun sub(self: FixedPoint64, y: FixedPoint64): FixedPoint64 {
+ let x_raw = get_raw_value(self);
+ let y_raw = get_raw_value(y);
+ assert!(x_raw >= y_raw, ENEGATIVE_RESULT);
+ create_from_raw_value(x_raw - y_raw)
+}
+
+
+
+
+
+
+## Function `sub_u64`
+
+
+
+public fun sub_u64(self: fixed_point64::FixedPoint64, y: u64): fixed_point64::FixedPoint64
+
+
+
+
+##### Implementation
+
+
+public fun sub_u64(self: FixedPoint64, y: u64): FixedPoint64 {
+ sub_u128(self, (y as u128))
+}
+
+
+
+
+
+
+## Function `sub_u128`
+
+
+
+public fun sub_u128(self: fixed_point64::FixedPoint64, y: u128): fixed_point64::FixedPoint64
+
+
+
+
+##### Implementation
+
+
+public fun sub_u128(self: FixedPoint64, y: u128): FixedPoint64 {
+ let x_raw = (get_raw_value(self) as u256);
+ let y_raw = (y as u256) << 64;
+ assert!(x_raw >= y_raw, ENEGATIVE_RESULT);
+ create_from_raw_value(((x_raw - y_raw) as u128))
+}
+
+
+
+
+
+
+## Function `add`
+
+Returns self + y. The result cannot be greater than MAX_U128.
+
+
+public fun add(self: fixed_point64::FixedPoint64, y: fixed_point64::FixedPoint64): fixed_point64::FixedPoint64
+
+
+
+
+##### Implementation
+
+
+public fun add(self: FixedPoint64, y: FixedPoint64): FixedPoint64 {
+ let x_raw = get_raw_value(self);
+ let y_raw = get_raw_value(y);
+ let result = (x_raw as u256) + (y_raw as u256);
+ assert!(result <= MAX_U128, ERATIO_OUT_OF_RANGE);
+ create_from_raw_value((result as u128))
+}
+
+
+
+
+
+
+## Function `add_u64`
+
+
+
+public fun add_u64(self: fixed_point64::FixedPoint64, y: u64): fixed_point64::FixedPoint64
+
+
+
+
+##### Implementation
+
+
+public fun add_u64(self: FixedPoint64, y: u64): FixedPoint64 {
+ add_u128(self, (y as u128))
+}
+
+
+
+
+
+
+## Function `add_u128`
+
+
+
+public fun add_u128(self: fixed_point64::FixedPoint64, y: u128): fixed_point64::FixedPoint64
+
+
+
+
+##### Implementation
+
+
+public fun add_u128(self: FixedPoint64, y: u128): FixedPoint64 {
+ let x_raw = (get_raw_value(self) as u256);
+ let y_raw = (y as u256) << 64;
+ let result = x_raw + y_raw;
+ assert!(result <= MAX_U128, ERATIO_OUT_OF_RANGE);
+ create_from_raw_value((result as u128))
+}
+
+
+
+
+
+
+## Function `multiply`
+
+
+
+public fun multiply(self: fixed_point64::FixedPoint64, y: fixed_point64::FixedPoint64): fixed_point64::FixedPoint64
+
+
+
+
+##### Implementation
+
+
+public fun multiply(self: FixedPoint64, y: FixedPoint64): FixedPoint64 {
+ let x_raw = get_raw_value(self);
+ let y_raw = get_raw_value(y);
+ let result = ((x_raw as u256) * (y_raw as u256)) >> 64;
+ assert!(result <= MAX_U128, EMULTIPLICATION);
+ create_from_raw_value((result as u128))
+}
+
+
+
+
+
+
+## Function `multiply_u64`
+
+
+
+public fun multiply_u64(val: u64, multiplier: fixed_point64::FixedPoint64): u64
+
+
+
+
+##### Implementation
+
+
+public fun multiply_u64(val: u64, multiplier: FixedPoint64): u64 {
+ let res = multiply_u128((val as u128), multiplier);
+ assert!(res <= MAX_U64, EMULTIPLICATION);
+ (res as u64)
+}
+
+
+
+
## Function `multiply_u128`
@@ -142,8 +431,7 @@ overflows.
-
-Implementation
+##### Implementation
public fun multiply_u128(val: u128, multiplier: FixedPoint64): u128 {
@@ -162,45 +450,79 @@ overflows.
-
+
-
-Specification
+## Function `divide`
-pragma opaque;
-include MultiplyAbortsIf;
-ensures result == spec_multiply_u128(val, multiplier);
+public fun divide(self: fixed_point64::FixedPoint64, divisor: fixed_point64::FixedPoint64): fixed_point64::FixedPoint64
+##### Implementation
-
-
-schema MultiplyAbortsIf {
- val: num;
- multiplier: FixedPoint64;
- aborts_if spec_multiply_u128(val, multiplier) > MAX_U128 with EMULTIPLICATION;
+public fun divide(self: FixedPoint64, divisor: FixedPoint64): FixedPoint64 {
+ // Check for division by zero.
+ assert!(divisor.value != 0, EDIVISION_BY_ZERO);
+ // Perform the division with 256 bits to avoid losing accuracy.
+ let result = ((self.value as u256) << 64) / (divisor.value as u256);
+ assert!(result <= MAX_U128, EDIVISION);
+ create_from_raw_value((result as u128))
}
+
+
+## Function `divide_u64`
+
+Divide a u64 integer by a fixed-point number, truncating any
+fractional part of the quotient. This will abort if the divisor
+is zero or if the quotient overflows.
+
+
+public fun divide_u64(val: u64, divisor: fixed_point64::FixedPoint64): u64
+
+
-
+##### Implementation
-fun spec_multiply_u128(val: num, multiplier: FixedPoint64): num {
- (val * multiplier.value) >> 64
+
+public fun divide_u64(val: u64, divisor: FixedPoint64): u64 {
+ let res = divide_u128((val as u128), divisor);
+ assert!(res <= MAX_U64, EDIVISION);
+ (res as u64)
}
-
+
+
+## Function `divide_by_u64`
+
+Divide a fixed-point number by a u64 integer.
+
+
+public fun divide_by_u64(val: fixed_point64::FixedPoint64, divisor: u64): fixed_point64::FixedPoint64
+
+
+
+
+##### Implementation
+
+
+public fun divide_by_u64(val: FixedPoint64, divisor: u64): FixedPoint64 {
+ divide_by_u128(val, (divisor as u128))
+}
+
+
+
@@ -216,8 +538,7 @@ is zero or if the quotient overflows.
-
-Implementation
+##### Implementation
public fun divide_u128(val: u128, divisor: FixedPoint64): u128 {
@@ -237,47 +558,30 @@ is zero or if the quotient overflows.
-
-
-
-Specification
-
-
-
-pragma opaque;
-include DivideAbortsIf;
-ensures result == spec_divide_u128(val, divisor);
-
-
-
+
+## Function `divide_by_u128`
-
+Divide a fixed-point number by a u128 integer.
-schema DivideAbortsIf {
- val: num;
- divisor: FixedPoint64;
- aborts_if divisor.value == 0 with EDIVISION_BY_ZERO;
- aborts_if spec_divide_u128(val, divisor) > MAX_U128 with EDIVISION;
-}
+public fun divide_by_u128(val: fixed_point64::FixedPoint64, divisor: u128): fixed_point64::FixedPoint64
-
-
+##### Implementation
-fun spec_divide_u128(val: num, divisor: FixedPoint64): num {
- (val << 64) / divisor.value
+public fun divide_by_u128(val: FixedPoint64, divisor: u128): FixedPoint64 {
+ // Check for division by zero.
+ assert!(divisor != 0, EDIVISION_BY_ZERO);
+ create_from_raw_value(get_raw_value(val) / divisor)
}
-
-
## Function `create_from_rational`
@@ -299,8 +603,7 @@ rounding, e.g., 0.0125 will round down to 0.012 instead of up to 0.013.
-
-Implementation
+##### Implementation
public fun create_from_rational(numerator: u128, denominator: u128): FixedPoint64 {
@@ -320,52 +623,6 @@ rounding, e.g., 0.0125 will round down to 0.012 instead of up to 0.013.
-
-
-
-Specification
-
-
-
-pragma opaque;
-pragma verify = false;
-include CreateFromRationalAbortsIf;
-ensures result == spec_create_from_rational(numerator, denominator);
-
-
-
-
-
-
-
-
-schema CreateFromRationalAbortsIf {
- numerator: u128;
- denominator: u128;
- let scaled_numerator = (numerator as u256)<< 64;
- let scaled_denominator = (denominator as u256);
- let quotient = scaled_numerator / scaled_denominator;
- aborts_if scaled_denominator == 0 with EDENOMINATOR;
- aborts_if quotient == 0 && scaled_numerator != 0 with ERATIO_OUT_OF_RANGE;
- aborts_if quotient > MAX_U128 with ERATIO_OUT_OF_RANGE;
-}
-
-
-
-
-
-
-
-
-fun spec_create_from_rational(numerator: num, denominator: num): FixedPoint64 {
- FixedPoint64{value: (numerator << 128) / (denominator << 64)}
-}
-
-
-
-
-
-
## Function `create_from_raw_value`
@@ -378,8 +635,7 @@ Create a fixedpoint value from a raw value.
-
-Implementation
+##### Implementation
public fun create_from_raw_value(value: u128): FixedPoint64 {
@@ -389,22 +645,6 @@ Create a fixedpoint value from a raw value.
-
-
-
-Specification
-
-
-
-pragma opaque;
-aborts_if false;
-ensures result.value == value;
-
-
-
-
-
-
## Function `get_raw_value`
@@ -414,24 +654,21 @@ adding or subtracting FixedPoint64 values, can be done using the raw
values directly.
-public fun get_raw_value(num: fixed_point64::FixedPoint64): u128
+public fun get_raw_value(self: fixed_point64::FixedPoint64): u128
-
-Implementation
+##### Implementation
-public fun get_raw_value(num: FixedPoint64): u128 {
- num.value
+public fun get_raw_value(self: FixedPoint64): u128 {
+ self.value
}
-
-
## Function `is_zero`
@@ -439,24 +676,21 @@ values directly.
Returns true if the ratio is zero.
-public fun is_zero(num: fixed_point64::FixedPoint64): bool
+public fun is_zero(self: fixed_point64::FixedPoint64): bool
-
-Implementation
+##### Implementation
-public fun is_zero(num: FixedPoint64): bool {
- num.value == 0
+public fun is_zero(self: FixedPoint64): bool {
+ self.value == 0
}
-
-
## Function `min`
@@ -469,52 +703,17 @@ Returns the smaller of the two FixedPoint64 numbers.
-
-Implementation
+##### Implementation
public fun min(num1: FixedPoint64, num2: FixedPoint64): FixedPoint64 {
- if (num1.value < num2.value) {
- num1
- } else {
- num2
- }
-}
-
-
-
-
-
-
-
-Specification
-
-
-
-pragma opaque;
-aborts_if false;
-ensures result == spec_min(num1, num2);
-
-
-
-
-
-
-
-
-fun spec_min(num1: FixedPoint64, num2: FixedPoint64): FixedPoint64 {
- if (num1.value < num2.value) {
- num1
- } else {
- num2
- }
+ if (num1.value < num2.value) { num1 }
+ else { num2 }
}
-
-
## Function `max`
@@ -527,305 +726,250 @@ Returns the larger of the two FixedPoint64 numbers.
-
-Implementation
+##### Implementation
public fun max(num1: FixedPoint64, num2: FixedPoint64): FixedPoint64 {
- if (num1.value > num2.value) {
- num1
- } else {
- num2
- }
+ if (num1.value > num2.value) { num1 }
+ else { num2 }
}
-
+
-
-Specification
+## Function `less_or_equal`
+Returns true if self <= num2
-pragma opaque;
-aborts_if false;
-ensures result == spec_max(num1, num2);
+public fun less_or_equal(self: fixed_point64::FixedPoint64, num2: fixed_point64::FixedPoint64): bool
-
-
+##### Implementation
-fun spec_max(num1: FixedPoint64, num2: FixedPoint64): FixedPoint64 {
- if (num1.value > num2.value) {
- num1
- } else {
- num2
- }
+public fun less_or_equal(self: FixedPoint64, num2: FixedPoint64): bool {
+ self.value <= num2.value
}
-
+
-
+## Function `less`
-## Function `create_from_u128`
-
-Create a fixedpoint value from a u128 value.
+Returns true if self < num2
-public fun create_from_u128(val: u128): fixed_point64::FixedPoint64
+public fun less(self: fixed_point64::FixedPoint64, num2: fixed_point64::FixedPoint64): bool
-
-Implementation
+##### Implementation
-public fun create_from_u128(val: u128): FixedPoint64 {
- let value = (val as u256) << 64;
- assert!(value <= MAX_U128, ERATIO_OUT_OF_RANGE);
- FixedPoint64 {value: (value as u128)}
+public fun less(self: FixedPoint64, num2: FixedPoint64): bool {
+ self.value < num2.value
}
-
-
-
-Specification
+
+## Function `greater_or_equal`
-
-pragma opaque;
-include CreateFromU64AbortsIf;
-ensures result == spec_create_from_u128(val);
-
-
+Returns true if self >= num2
-
-
-
-
-schema CreateFromU64AbortsIf {
- val: num;
- let scaled_value = (val as u256) << 64;
- aborts_if scaled_value > MAX_U128;
-}
+public fun greater_or_equal(self: fixed_point64::FixedPoint64, num2: fixed_point64::FixedPoint64): bool
+##### Implementation
-
-
-fun spec_create_from_u128(val: num): FixedPoint64 {
- FixedPoint64 {value: val << 64}
+public fun greater_or_equal(self: FixedPoint64, num2: FixedPoint64): bool {
+ self.value >= num2.value
}
-
-
-
+
-## Function `floor`
+## Function `greater`
-Returns the largest integer less than or equal to a given number.
+Returns true if self > num2
-public fun floor(num: fixed_point64::FixedPoint64): u128
+public fun greater(self: fixed_point64::FixedPoint64, num2: fixed_point64::FixedPoint64): bool
-
-Implementation
+##### Implementation
-public fun floor(num: FixedPoint64): u128 {
- num.value >> 64
+public fun greater(self: FixedPoint64, num2: FixedPoint64): bool {
+ self.value > num2.value
}
-
+
-
-Specification
+## Function `equal`
+Returns true if self = num2
-pragma opaque;
-aborts_if false;
-ensures result == spec_floor(num);
+public fun equal(self: fixed_point64::FixedPoint64, num2: fixed_point64::FixedPoint64): bool
-
-
+##### Implementation
-fun spec_floor(val: FixedPoint64): u128 {
- let fractional = val.value % (1 << 64);
- if (fractional == 0) {
- val.value >> 64
- } else {
- (val.value - fractional) >> 64
- }
+public fun equal(self: FixedPoint64, num2: FixedPoint64): bool {
+ self.value == num2.value
}
-
+
-
+## Function `almost_equal`
-## Function `ceil`
+Returns true if self almost equals to num2, which means abs(num1-num2) <= precision
-Rounds up the given FixedPoint64 to the next largest integer.
-
-public fun ceil(num: fixed_point64::FixedPoint64): u128
+public fun almost_equal(self: fixed_point64::FixedPoint64, num2: fixed_point64::FixedPoint64, precision: fixed_point64::FixedPoint64): bool
-
-Implementation
+##### Implementation
-public fun ceil(num: FixedPoint64): u128 {
- let floored_num = floor(num) << 64;
- if (num.value == floored_num) {
- return floored_num >> 64
- };
- let val = ((floored_num as u256) + (1 << 64));
- (val >> 64 as u128)
+public fun almost_equal(
+ self: FixedPoint64, num2: FixedPoint64, precision: FixedPoint64
+): bool {
+ if (self.value > num2.value) {
+ (self.value - num2.value <= precision.value)
+ } else {
+ (num2.value - self.value <= precision.value)
+ }
}
-
-
-
-Specification
+
+## Function `create_from_u128`
-TODO: worked in the past but started to time out since last z3 update
+Create a fixedpoint value from a u128 value.
-pragma verify = false;
-pragma opaque;
-aborts_if false;
-ensures result == spec_ceil(num);
+public fun create_from_u128(val: u128): fixed_point64::FixedPoint64
-
-
+##### Implementation
-fun spec_ceil(val: FixedPoint64): u128 {
- let fractional = val.value % (1 << 64);
- let one = 1 << 64;
- if (fractional == 0) {
- val.value >> 64
- } else {
- (val.value - fractional + one) >> 64
- }
+public fun create_from_u128(val: u128): FixedPoint64 {
+ let value = (val as u256) << 64;
+ assert!(value <= MAX_U128, ERATIO_OUT_OF_RANGE);
+ FixedPoint64 { value: (value as u128) }
}
-
-
-
+
-## Function `round`
+## Function `floor`
-Returns the value of a FixedPoint64 to the nearest integer.
+Returns the largest integer less than or equal to a given number.
-public fun round(num: fixed_point64::FixedPoint64): u128
+public fun floor(self: fixed_point64::FixedPoint64): u128
-
-Implementation
+##### Implementation
-public fun round(num: FixedPoint64): u128 {
- let floored_num = floor(num) << 64;
- let boundary = floored_num + ((1 << 64) / 2);
- if (num.value < boundary) {
- floored_num >> 64
- } else {
- ceil(num)
- }
+public fun floor(self: FixedPoint64): u128 {
+ self.value >> 64
}
-
+
-
-Specification
+## Function `ceil`
+Rounds up the given FixedPoint64 to the next largest integer.
-pragma opaque;
-aborts_if false;
-ensures result == spec_round(num);
+public fun ceil(self: fixed_point64::FixedPoint64): u128
-
-
+##### Implementation
-fun spec_round(val: FixedPoint64): u128 {
- let fractional = val.value % (1 << 64);
- let boundary = (1 << 64) / 2;
- let one = 1 << 64;
- if (fractional < boundary) {
- (val.value - fractional) >> 64
- } else {
- (val.value - fractional + one) >> 64
- }
+public fun ceil(self: FixedPoint64): u128 {
+ let floored_num = floor(self) << 64;
+ if (self.value == floored_num) {
+ return floored_num >> 64
+ };
+ let val = ((floored_num as u256) + (1 << 64));
+ (val >> 64 as u128)
}
-
+
+
+## Function `round`
+
+Returns the value of a FixedPoint64 to the nearest integer.
+
-
+public fun round(self: fixed_point64::FixedPoint64): u128
+
-## Module Specification
+##### Implementation
-pragma aborts_if_is_strict;
+public fun round(self: FixedPoint64): u128 {
+ let floored_num = floor(self) << 64;
+ let boundary = floored_num + ((1 << 64) / 2);
+ if (self.value < boundary) {
+ floored_num >> 64
+ } else {
+ ceil(self)
+ }
+}
diff --git a/initia_stdlib/doc/from_bcs.md b/initia_stdlib/doc/from_bcs.md
index 34e36ce..1cc6479 100644
--- a/initia_stdlib/doc/from_bcs.md
+++ b/initia_stdlib/doc/from_bcs.md
@@ -64,8 +64,7 @@ UTF8 check failed in conversion from bytes to string
-
-Implementation
+##### Implementation
public fun to_bool(v: vector<u8>): bool {
@@ -75,8 +74,6 @@ UTF8 check failed in conversion from bytes to string
-
-
## Function `to_u8`
@@ -88,8 +85,7 @@ UTF8 check failed in conversion from bytes to string
-
-Implementation
+##### Implementation
public fun to_u8(v: vector<u8>): u8 {
@@ -99,8 +95,6 @@ UTF8 check failed in conversion from bytes to string
-
-
## Function `to_u16`
@@ -112,8 +106,7 @@ UTF8 check failed in conversion from bytes to string
-
-Implementation
+##### Implementation
public fun to_u16(v: vector<u8>): u16 {
@@ -123,8 +116,6 @@ UTF8 check failed in conversion from bytes to string
-
-
## Function `to_u32`
@@ -136,8 +127,7 @@ UTF8 check failed in conversion from bytes to string
-
-Implementation
+##### Implementation
public fun to_u32(v: vector<u8>): u32 {
@@ -147,8 +137,6 @@ UTF8 check failed in conversion from bytes to string
-
-
## Function `to_u64`
@@ -160,8 +148,7 @@ UTF8 check failed in conversion from bytes to string
-
-Implementation
+##### Implementation
public fun to_u64(v: vector<u8>): u64 {
@@ -171,8 +158,6 @@ UTF8 check failed in conversion from bytes to string
-
-
## Function `to_u128`
@@ -184,8 +169,7 @@ UTF8 check failed in conversion from bytes to string
-
-Implementation
+##### Implementation
public fun to_u128(v: vector<u8>): u128 {
@@ -195,8 +179,6 @@ UTF8 check failed in conversion from bytes to string
-
-
## Function `to_u256`
@@ -208,8 +190,7 @@ UTF8 check failed in conversion from bytes to string
-
-Implementation
+##### Implementation
public fun to_u256(v: vector<u8>): u256 {
@@ -219,8 +200,6 @@ UTF8 check failed in conversion from bytes to string
-
-
## Function `to_address`
@@ -232,8 +211,7 @@ UTF8 check failed in conversion from bytes to string
-
-Implementation
+##### Implementation
public fun to_address(v: vector<u8>): address {
@@ -243,8 +221,6 @@ UTF8 check failed in conversion from bytes to string
-
-
## Function `to_bytes`
@@ -256,8 +232,7 @@ UTF8 check failed in conversion from bytes to string
-
-Implementation
+##### Implementation
public fun to_bytes(v: vector<u8>): vector<u8> {
@@ -267,8 +242,6 @@ UTF8 check failed in conversion from bytes to string
-
-
## Function `to_vector_bytes`
@@ -280,8 +253,7 @@ UTF8 check failed in conversion from bytes to string
-
-Implementation
+##### Implementation
public fun to_vector_bytes(v: vector<u8>): vector<vector<u8>> {
@@ -291,8 +263,6 @@ UTF8 check failed in conversion from bytes to string
-
-
## Function `to_vector_string`
@@ -304,19 +274,26 @@ UTF8 check failed in conversion from bytes to string
-
-Implementation
+##### Implementation
public fun to_vector_string(v: vector<u8>): vector<String> {
- from_bytes<vector<String>>(v)
+ let vec_string = from_bytes<vector<String>>(v);
+ vector::for_each_ref(
+ &vec_string,
+ |s| {
+ assert!(
+ string::internal_check_utf8(string::bytes(s)),
+ EINVALID_UTF8
+ );
+ }
+ );
+ vec_string
}
-
-
## Function `to_string`
@@ -328,22 +305,22 @@ UTF8 check failed in conversion from bytes to string
-
-Implementation
+##### Implementation
public fun to_string(v: vector<u8>): String {
// To make this safe, we need to evaluate the utf8 invariant.
let s = from_bytes<String>(v);
- assert!(string::internal_check_utf8(string::bytes(&s)), EINVALID_UTF8);
+ assert!(
+ string::internal_check_utf8(string::bytes(&s)),
+ EINVALID_UTF8
+ );
s
}
-
-
## Function `from_bytes`
@@ -360,13 +337,8 @@ owned.
-
-Implementation
+##### Implementation
public(friend) native fun from_bytes<T>(bytes: vector<u8>): T;
-
-
-
-
diff --git a/initia_stdlib/doc/function_info.md b/initia_stdlib/doc/function_info.md
new file mode 100644
index 0000000..b3e16cc
--- /dev/null
+++ b/initia_stdlib/doc/function_info.md
@@ -0,0 +1,214 @@
+
+
+
+# Module `0x1::function_info`
+
+The function_info
module defines the FunctionInfo
type which simulates a function pointer.
+
+
+- [Struct `FunctionInfo`](#0x1_function_info_FunctionInfo)
+- [Constants](#@Constants_0)
+- [Function `new_function_info`](#0x1_function_info_new_function_info)
+- [Function `new_function_info_from_address`](#0x1_function_info_new_function_info_from_address)
+- [Function `check_dispatch_type_compatibility`](#0x1_function_info_check_dispatch_type_compatibility)
+- [Function `load_module_from_function`](#0x1_function_info_load_module_from_function)
+
+
+use 0x1::signer;
+use 0x1::string;
+
+
+
+
+
+
+## Struct `FunctionInfo`
+
+A String
holds a sequence of bytes which is guaranteed to be in utf8 format.
+
+
+struct FunctionInfo has copy, drop, store
+
+
+
+
+##### Fields
+
+
+
+-
+
module_address: address
+
+-
+
+
+-
+
module_name: string::String
+
+-
+
+
+-
+
function_name: string::String
+
+-
+
+
+
+
+
+
+
+## Constants
+
+
+
+
+Function specified in the FunctionInfo doesn't exist on chain.
+
+
+const EINVALID_FUNCTION: u64 = 2;
+
+
+
+
+
+
+String is not a valid Move identifier
+
+
+const EINVALID_IDENTIFIER: u64 = 1;
+
+
+
+
+
+
+Feature hasn't been activated yet.
+
+
+const ENOT_ACTIVATED: u64 = 3;
+
+
+
+
+
+
+## Function `new_function_info`
+
+Creates a new function info from names.
+
+
+public fun new_function_info(module_signer: &signer, module_name: string::String, function_name: string::String): function_info::FunctionInfo
+
+
+
+
+##### Implementation
+
+
+public fun new_function_info(
+ module_signer: &signer, module_name: String, function_name: String
+): FunctionInfo {
+ new_function_info_from_address(
+ signer::address_of(module_signer),
+ module_name,
+ function_name
+ )
+}
+
+
+
+
+
+
+## Function `new_function_info_from_address`
+
+
+
+public(friend) fun new_function_info_from_address(module_address: address, module_name: string::String, function_name: string::String): function_info::FunctionInfo
+
+
+
+
+##### Implementation
+
+
+public(friend) fun new_function_info_from_address(
+ module_address: address, module_name: String, function_name: String
+): FunctionInfo {
+ assert!(
+ is_identifier(string::bytes(&module_name)),
+ EINVALID_IDENTIFIER
+ );
+ assert!(
+ is_identifier(string::bytes(&function_name)),
+ EINVALID_IDENTIFIER
+ );
+ FunctionInfo { module_address, module_name, function_name }
+}
+
+
+
+
+
+
+## Function `check_dispatch_type_compatibility`
+
+Check if the dispatch target function meets the type requirements of the disptach entry point.
+
+framework_function is the dispatch native function defined in the initia_std.
+dispatch_target is the function passed in by the user.
+
+dispatch_target should have the same signature (same argument type, same generics constraint) except
+that the framework_function will have a &FunctionInfo
in the last argument that will instruct the VM which
+function to jump to.
+
+dispatch_target also needs to be public so the type signature will remain unchanged.
+
+
+public(friend) fun check_dispatch_type_compatibility(framework_function: &function_info::FunctionInfo, dispatch_target: &function_info::FunctionInfo): bool
+
+
+
+
+##### Implementation
+
+
+public(friend) fun check_dispatch_type_compatibility(
+ framework_function: &FunctionInfo, dispatch_target: &FunctionInfo
+): bool {
+ load_function_impl(dispatch_target);
+ check_dispatch_type_compatibility_impl(framework_function, dispatch_target)
+}
+
+
+
+
+
+
+## Function `load_module_from_function`
+
+Load up a function into VM's loader and charge for its dependencies
+
+It is **critical** to make sure that this function is invoked before check_dispatch_type_compatibility
+or performing any other dispatching logic to ensure:
+1. We properly charge gas for the function to dispatch.
+2. The function is loaded in the cache so that we can perform further type checking/dispatching logic.
+
+Calling check_dispatch_type_compatibility_impl
or dispatch without loading up the module would yield an error
+if such module isn't accessed previously in the transaction.
+
+
+public(friend) fun load_module_from_function(f: &function_info::FunctionInfo)
+
+
+
+
+##### Implementation
+
+
+public(friend) fun load_module_from_function(f: &FunctionInfo) {
+ load_function_impl(f)
+}
+
diff --git a/initia_stdlib/doc/fungible_asset.md b/initia_stdlib/doc/fungible_asset.md
index 13bc6e2..3b9f93e 100644
--- a/initia_stdlib/doc/fungible_asset.md
+++ b/initia_stdlib/doc/fungible_asset.md
@@ -11,9 +11,12 @@ metadata object can be any object that equipped with use 0x1::error;
+use 0x1::account;
+use 0x1::error;
use 0x1::event;
+use 0x1::function_info;
use 0x1::object;
use 0x1::option;
use 0x1::signer;
@@ -88,8 +105,7 @@ metadata object can be any object that equipped with
-
-
## Resource `Metadata`
@@ -117,13 +131,12 @@ metadata object can be any object that equipped with Metadata has key
+struct Metadata has copy, drop, key
-
-Fields
+##### Fields
@@ -164,8 +177,6 @@ Metadata of a Fungible asset
-
-
## Resource `FungibleStore`
@@ -178,8 +189,7 @@ The store object that holds fungible assets of a specific type associated with a
-
-Fields
+##### Fields
@@ -204,8 +214,6 @@ The store object that holds fungible assets of a specific type associated with a
-
-
## Struct `FungibleAsset`
@@ -219,8 +227,7 @@ FungibleAsset is ephemeral and cannot be stored directly. It must be deposited b
-
-Fields
+##### Fields
@@ -239,7 +246,65 @@ FungibleAsset is ephemeral and cannot be stored directly. It must be deposited b
-
+
+
+## Resource `DispatchFunctionStore`
+
+
+
+struct DispatchFunctionStore has key
+
+
+
+
+##### Fields
+
+
+
+-
+
withdraw_function: option::Option<function_info::FunctionInfo>
+
+-
+
+
+-
+
deposit_function: option::Option<function_info::FunctionInfo>
+
+-
+
+
+-
+
derived_balance_function: option::Option<function_info::FunctionInfo>
+
+-
+
+
+
+
+
+
+
+## Resource `DeriveSupply`
+
+
+
+struct DeriveSupply has key
+
+
+
+
+##### Fields
+
+
+
+-
+
dispatch_function: option::Option<function_info::FunctionInfo>
+
+-
+
+
+
+
@@ -253,8 +318,7 @@ MintRef can be used to mint the fungible asset into an account's store.
-
-Fields
+##### Fields
@@ -267,8 +331,6 @@ MintRef can be used to mint the fungible asset into an account's store.
-
-
## Struct `TransferRef`
@@ -282,8 +344,7 @@ and allow the holder of TransferRef to transfer fungible assets from any account
-
-Fields
+##### Fields
@@ -296,8 +357,6 @@ and allow the holder of TransferRef to transfer fungible assets from any account
-
-
## Struct `BurnRef`
@@ -310,8 +369,7 @@ BurnRef can be used to burn fungible assets from a given holder account.
-
-Fields
+##### Fields
@@ -324,7 +382,30 @@ BurnRef can be used to burn fungible assets from a given holder account.
-
+
+
+## Struct `MutateMetadataRef`
+
+MutateMetadataRef can be used to directly modify the fungible asset's Metadata.
+
+
+struct MutateMetadataRef has drop, store
+
+
+
+
+##### Fields
+
+
+
+-
+
metadata: object::Object<fungible_asset::Metadata>
+
+-
+
+
+
+
@@ -339,8 +420,7 @@ Emitted when fungible assets are deposited into a store.
-
-Fields
+##### Fields
@@ -365,8 +445,6 @@ Emitted when fungible assets are deposited into a store.
-
-
## Struct `WithdrawEvent`
@@ -380,8 +458,7 @@ Emitted when fungible assets are withdrawn from a store.
-
-Fields
+##### Fields
@@ -406,8 +483,6 @@ Emitted when fungible assets are withdrawn from a store.
-
-
## Struct `FrozenEvent`
@@ -421,8 +496,7 @@ Emitted when a store's frozen status is updated.
-
-Fields
+##### Fields
@@ -447,8 +521,6 @@ Emitted when a store's frozen status is updated.
-
-
## Struct `BurnEvent`
@@ -462,8 +534,7 @@ Emitted when fungible assets are burnt.
-
-Fields
+##### Fields
@@ -482,8 +553,6 @@ Emitted when fungible assets are burnt.
-
-
## Struct `MintEvent`
@@ -497,8 +566,7 @@ Emitted when fungible assets are minted.
-
-Fields
+##### Fields
@@ -517,8 +585,6 @@ Emitted when fungible assets are minted.
-
-
## Constants
@@ -534,6 +600,16 @@ Maximum possible coin supply.
+
+
+Trying to re-register dispatch hook on a fungible asset.
+
+
+const EALREADY_REGISTERED: u64 = 29;
+
+
+
+
Cannot destroy non-empty fungible assets.
@@ -544,6 +620,16 @@ Cannot destroy non-empty fungible assets.
+
+
+Cannot register dispatch hook for APT.
+
+
+const EAPT_NOT_DISPATCHABLE: u64 = 31;
+
+
+
+
Cannot destroy fungible stores with a non-zero balance.
@@ -574,6 +660,26 @@ Burn ref and store do not match.
+
+
+Deposit to a blocked account is not allowed._
+
+
+const ECANNOT_DEPOSIT_TO_BLOCKED_ACCOUNT: u64 = 92;
+
+
+
+
+
+
+Module account store cannot be manipulated.
+
+
+const ECONNOT_MANIPULATE_MODULE_ACCOUNT_STORE: u64 = 91;
+
+
+
+
Decimals is over the maximum of 32
@@ -584,6 +690,36 @@ Decimals is over the maximum of 32
+
+
+Provided deposit function type doesn't meet the signature requirement.
+
+
+const EDEPOSIT_FUNCTION_SIGNATURE_MISMATCH: u64 = 26;
+
+
+
+
+
+
+Provided derived_balance function type doesn't meet the signature requirement.
+
+
+const EDERIVED_BALANCE_FUNCTION_SIGNATURE_MISMATCH: u64 = 27;
+
+
+
+
+
+
+Provided derived_supply function type doesn't meet the signature requirement.
+
+
+const EDERIVED_SUPPLY_FUNCTION_SIGNATURE_MISMATCH: u64 = 33;
+
+
+
+
Fungible asset and store do not match.
@@ -604,6 +740,26 @@ Fungible asset do not match when merging.
+
+
+Fungible metadata does not exist on this account.
+
+
+const EFUNGIBLE_METADATA_EXISTENCE: u64 = 30;
+
+
+
+
+
+
+Flag for the existence of fungible store.
+
+
+const EFUNGIBLE_STORE_EXISTENCE: u64 = 23;
+
+
+
+
Insufficient balance to withdraw or transfer.
@@ -614,6 +770,17 @@ Insufficient balance to withdraw or transfer.
+
+
+Invalid withdraw/deposit on dispatchable token. The specified token has a dispatchable function hook.
+Need to invoke dispatchable_fungible_asset::withdraw/deposit to perform transfer.
+
+
+const EINVALID_DISPATCHABLE_OPERATIONS: u64 = 28;
+
+
+
+
The fungible asset's supply has exceeded maximum.
@@ -644,6 +811,16 @@ Name of the fungible asset metadata is too long
+
+
+Account is not the owner of metadata object.
+
+
+const ENOT_METADATA_OWNER: u64 = 24;
+
+
+
+
Account is not the store's owner.
@@ -734,6 +911,16 @@ URI for the icon of the fungible asset metadata is too long
+
+
+Provided withdraw function type doesn't meet the signature requirement.
+
+
+const EWITHDRAW_FUNCTION_SIGNATURE_MISMATCH: u64 = 25;
+
+
+
+
@@ -788,8 +975,7 @@ maximum_supply defines the behavior of maximum supply when monitoring:
-
-Implementation
+##### Implementation
public fun add_fungibility(
@@ -799,34 +985,47 @@ maximum_supply defines the behavior of maximum supply when monitoring:
symbol: String,
decimals: u8,
icon_uri: String,
- project_uri: String,
+ project_uri: String
): Object<Metadata> {
- assert!(!object::can_generate_delete_ref(constructor_ref), error::invalid_argument(EOBJECT_IS_DELETABLE));
+ assert!(
+ !object::can_generate_delete_ref(constructor_ref),
+ error::invalid_argument(EOBJECT_IS_DELETABLE)
+ );
let metadata_object_signer = &object::generate_signer(constructor_ref);
// metadata validations
- assert!(string::length(&name) <= MAX_NAME_LENGTH, error::out_of_range(ENAME_TOO_LONG));
- assert!(string::length(&symbol) <= MAX_SYMBOL_LENGTH, error::out_of_range(ESYMBOL_TOO_LONG));
- assert!(decimals <= MAX_DECIMALS, error::out_of_range(EDECIMALS_TOO_LARGE));
- assert!(string::length(&icon_uri) <= MAX_URI_LENGTH, error::out_of_range(EURI_TOO_LONG));
- assert!(string::length(&project_uri) <= MAX_URI_LENGTH, error::out_of_range(EURI_TOO_LONG));
+ assert!(
+ string::length(&name) <= MAX_NAME_LENGTH,
+ error::out_of_range(ENAME_TOO_LONG)
+ );
+ assert!(
+ string::length(&symbol) <= MAX_SYMBOL_LENGTH,
+ error::out_of_range(ESYMBOL_TOO_LONG)
+ );
+ assert!(
+ decimals <= MAX_DECIMALS,
+ error::out_of_range(EDECIMALS_TOO_LARGE)
+ );
+ assert!(
+ string::length(&icon_uri) <= MAX_URI_LENGTH,
+ error::out_of_range(EURI_TOO_LONG)
+ );
+ assert!(
+ string::length(&project_uri) <= MAX_URI_LENGTH,
+ error::out_of_range(EURI_TOO_LONG)
+ );
// store metadata
- move_to(metadata_object_signer,
- Metadata {
- name,
- symbol,
- decimals,
- icon_uri,
- project_uri,
- }
+ move_to(
+ metadata_object_signer,
+ Metadata { name, symbol, decimals, icon_uri, project_uri }
);
// store supply
- move_to(metadata_object_signer, Supply {
- current: 0,
- maximum: maximum_supply
- });
+ move_to(
+ metadata_object_signer,
+ Supply { current: 0, maximum: maximum_supply }
+ );
// return metadata object
object::object_from_constructor_ref<Metadata>(constructor_ref)
@@ -835,7 +1034,169 @@ maximum_supply defines the behavior of maximum supply when monitoring:
-
+
+
+## Function `register_dispatch_functions`
+
+Create a fungible asset store whose transfer rule would be overloaded by the provided function.
+
+
+public(friend) fun register_dispatch_functions(constructor_ref: &object::ConstructorRef, withdraw_function: option::Option<function_info::FunctionInfo>, deposit_function: option::Option<function_info::FunctionInfo>, derived_balance_function: option::Option<function_info::FunctionInfo>)
+
+
+
+
+##### Implementation
+
+
+public(friend) fun register_dispatch_functions(
+ constructor_ref: &ConstructorRef,
+ withdraw_function: Option<FunctionInfo>,
+ deposit_function: Option<FunctionInfo>,
+ derived_balance_function: Option<FunctionInfo>
+) {
+ // Verify that caller type matches callee type so wrongly typed function cannot be registered.
+ option::for_each_ref(
+ &withdraw_function,
+ |withdraw_function| {
+ let dispatcher_withdraw_function_info =
+ function_info::new_function_info_from_address(
+ @initia_std,
+ string::utf8(b"dispatchable_fungible_asset"),
+ string::utf8(b"dispatchable_withdraw")
+ );
+
+ assert!(
+ function_info::check_dispatch_type_compatibility(
+ &dispatcher_withdraw_function_info,
+ withdraw_function
+ ),
+ error::invalid_argument(EWITHDRAW_FUNCTION_SIGNATURE_MISMATCH)
+ );
+ }
+ );
+
+ option::for_each_ref(
+ &deposit_function,
+ |deposit_function| {
+ let dispatcher_deposit_function_info =
+ function_info::new_function_info_from_address(
+ @initia_std,
+ string::utf8(b"dispatchable_fungible_asset"),
+ string::utf8(b"dispatchable_deposit")
+ );
+ // Verify that caller type matches callee type so wrongly typed function cannot be registered.
+ assert!(
+ function_info::check_dispatch_type_compatibility(
+ &dispatcher_deposit_function_info,
+ deposit_function
+ ),
+ error::invalid_argument(EDEPOSIT_FUNCTION_SIGNATURE_MISMATCH)
+ );
+ }
+ );
+
+ option::for_each_ref(
+ &derived_balance_function,
+ |balance_function| {
+ let dispatcher_derived_balance_function_info =
+ function_info::new_function_info_from_address(
+ @initia_std,
+ string::utf8(b"dispatchable_fungible_asset"),
+ string::utf8(b"dispatchable_derived_balance")
+ );
+ // Verify that caller type matches callee type so wrongly typed function cannot be registered.
+ assert!(
+ function_info::check_dispatch_type_compatibility(
+ &dispatcher_derived_balance_function_info,
+ balance_function
+ ),
+ error::invalid_argument(
+ EDERIVED_BALANCE_FUNCTION_SIGNATURE_MISMATCH
+ )
+ );
+ }
+ );
+ register_dispatch_function_sanity_check(constructor_ref);
+ assert!(
+ !exists<DispatchFunctionStore>(
+ object::address_from_constructor_ref(constructor_ref)
+ ),
+ error::already_exists(EALREADY_REGISTERED)
+ );
+
+ let store_obj = &object::generate_signer(constructor_ref);
+
+ // Store the overload function hook.
+ move_to<DispatchFunctionStore>(
+ store_obj,
+ DispatchFunctionStore {
+ withdraw_function,
+ deposit_function,
+ derived_balance_function
+ }
+ );
+}
+
+
+
+
+
+
+## Function `register_derive_supply_dispatch_function`
+
+Define the derived supply dispatch with the provided function.
+
+
+public(friend) fun register_derive_supply_dispatch_function(constructor_ref: &object::ConstructorRef, dispatch_function: option::Option<function_info::FunctionInfo>)
+
+
+
+
+##### Implementation
+
+
+public(friend) fun register_derive_supply_dispatch_function(
+ constructor_ref: &ConstructorRef, dispatch_function: Option<FunctionInfo>
+) {
+ // Verify that caller type matches callee type so wrongly typed function cannot be registered.
+ option::for_each_ref(
+ &dispatch_function,
+ |supply_function| {
+ let function_info =
+ function_info::new_function_info_from_address(
+ @initia_std,
+ string::utf8(b"dispatchable_fungible_asset"),
+ string::utf8(b"dispatchable_derived_supply")
+ );
+ // Verify that caller type matches callee type so wrongly typed function cannot be registered.
+ assert!(
+ function_info::check_dispatch_type_compatibility(
+ &function_info,
+ supply_function
+ ),
+ error::invalid_argument(
+ EDERIVED_SUPPLY_FUNCTION_SIGNATURE_MISMATCH
+ )
+ );
+ }
+ );
+ register_dispatch_function_sanity_check(constructor_ref);
+ assert!(
+ !exists<DeriveSupply>(
+ object::address_from_constructor_ref(constructor_ref)
+ ),
+ error::already_exists(EALREADY_REGISTERED)
+ );
+
+ let store_obj = &object::generate_signer(constructor_ref);
+
+ // Store the overload function hook.
+ move_to<DeriveSupply>(store_obj, DeriveSupply { dispatch_function });
+}
+
+
+
@@ -850,8 +1211,7 @@ This can only be called at object creation time as constructor_ref is only avail
-
-Implementation
+##### Implementation
public fun generate_mint_ref(constructor_ref: &ConstructorRef): MintRef {
@@ -862,8 +1222,6 @@ This can only be called at object creation time as constructor_ref is only avail
-
-
## Function `generate_burn_ref`
@@ -877,8 +1235,7 @@ This can only be called at object creation time as constructor_ref is only avail
-
-Implementation
+##### Implementation
public fun generate_burn_ref(constructor_ref: &ConstructorRef): BurnRef {
@@ -889,8 +1246,6 @@ This can only be called at object creation time as constructor_ref is only avail
-
-
## Function `generate_transfer_ref`
@@ -905,8 +1260,7 @@ This can only be called at object creation time as constructor_ref is only avail
-
-Implementation
+##### Implementation
public fun generate_transfer_ref(constructor_ref: &ConstructorRef): TransferRef {
@@ -917,7 +1271,32 @@ This can only be called at object creation time as constructor_ref is only avail
-
+
+
+## Function `generate_mutate_metadata_ref`
+
+Creates a mutate metadata ref that can be used to change the metadata information of fungible assets from the
+given fungible object's constructor ref.
+This can only be called at object creation time as constructor_ref is only available then.
+
+
+public fun generate_mutate_metadata_ref(constructor_ref: &object::ConstructorRef): fungible_asset::MutateMetadataRef
+
+
+
+
+##### Implementation
+
+
+public fun generate_mutate_metadata_ref(
+ constructor_ref: &ConstructorRef
+): MutateMetadataRef {
+ let metadata = object::object_from_constructor_ref<Metadata>(constructor_ref);
+ MutateMetadataRef { metadata }
+}
+
+
+
@@ -932,8 +1311,7 @@ Retrun true if given address has Metadata else return false
-
-Implementation
+##### Implementation
public fun is_fungible_asset(metadata_addr: address): bool {
@@ -943,8 +1321,6 @@ Retrun true if given address has Metadata else return false
-
-
## Function `supply`
@@ -958,12 +1334,11 @@ Get the current supply from the metadata
object.
-
-Implementation
+##### Implementation
public fun supply<T: key>(metadata: Object<T>): Option<u128> acquires Supply {
- let metadata_address = object::object_address(metadata);
+ let metadata_address = object::object_address(&metadata);
if (exists<Supply>(metadata_address)) {
let supply = borrow_global<Supply>(metadata_address);
option::some(supply.current)
@@ -975,8 +1350,6 @@ Get the current supply from the metadata
object.
-
-
## Function `maximum`
@@ -990,12 +1363,11 @@ Get the maximum supply from the metadata
object.
-
-Implementation
+##### Implementation
public fun maximum<T: key>(metadata: Object<T>): Option<u128> acquires Supply {
- let metadata_address = object::object_address(metadata);
+ let metadata_address = object::object_address(&metadata);
if (exists<Supply>(metadata_address)) {
let supply = borrow_global<Supply>(metadata_address);
supply.maximum
@@ -1007,8 +1379,6 @@ Get the maximum supply from the metadata
object.
-
-
## Function `name`
@@ -1022,19 +1392,16 @@ Get the name of the fungible asset from the metadata
object.
-
-Implementation
+##### Implementation
public fun name<T: key>(metadata: Object<T>): String acquires Metadata {
- borrow_fungible_metadata(metadata).name
+ borrow_fungible_metadata(&metadata).name
}
-
-
## Function `symbol`
@@ -1048,48 +1415,111 @@ Get the symbol of the fungible asset from the metadata
object.
-
-Implementation
+##### Implementation
public fun symbol<T: key>(metadata: Object<T>): String acquires Metadata {
- borrow_fungible_metadata(metadata).symbol
+ borrow_fungible_metadata(&metadata).symbol
}
-
+
-
-
-## Function `decimals`
+## Function `icon_uri`
-Get the decimals from the metadata
object.
+Get the icon uri from the metadata
object.
#[view]
-public fun decimals<T: key>(metadata: object::Object<T>): u8
+public fun icon_uri<T: key>(metadata: object::Object<T>): string::String
-
-Implementation
+##### Implementation
-public fun decimals<T: key>(metadata: Object<T>): u8 acquires Metadata {
- borrow_fungible_metadata(metadata).decimals
+public fun icon_uri<T: key>(metadata: Object<T>): String acquires Metadata {
+ borrow_fungible_metadata(&metadata).icon_uri
}
-
+
-
+## Function `project_uri`
-## Function `store_exists`
+Get the project uri from the metadata
object.
+
+
+#[view]
+public fun project_uri<T: key>(metadata: object::Object<T>): string::String
+
+
+
+
+##### Implementation
+
+
+public fun project_uri<T: key>(metadata: Object<T>): String acquires Metadata {
+ borrow_fungible_metadata(&metadata).project_uri
+}
+
+
+
+
+
+
+## Function `metadata`
+
+Get the metadata struct from the metadata
object.
+
+
+#[view]
+public fun metadata<T: key>(metadata: object::Object<T>): fungible_asset::Metadata
+
+
+
+
+##### Implementation
+
+
+public fun metadata<T: key>(metadata: Object<T>): Metadata acquires Metadata {
+ *borrow_fungible_metadata(&metadata)
+}
+
+
+
+
+
+
+## Function `decimals`
+
+Get the decimals from the metadata
object.
+
+
+#[view]
+public fun decimals<T: key>(metadata: object::Object<T>): u8
+
+
+
+
+##### Implementation
+
+
+public fun decimals<T: key>(metadata: Object<T>): u8 acquires Metadata {
+ borrow_fungible_metadata(&metadata).decimals
+}
+
+
+
+
+
+
+## Function `store_exists`
Return whether the provided address has a store initialized.
@@ -1100,8 +1530,7 @@ Return whether the provided address has a store initialized.
-
-Implementation
+##### Implementation
public fun store_exists(store: address): bool {
@@ -1111,8 +1540,6 @@ Return whether the provided address has a store initialized.
-
-
## Function `metadata_from_asset`
@@ -1125,8 +1552,7 @@ Return the underlying metadata object
-
-Implementation
+##### Implementation
public fun metadata_from_asset(fa: &FungibleAsset): Object<Metadata> {
@@ -1136,8 +1562,6 @@ Return the underlying metadata object
-
-
## Function `store_metadata`
@@ -1151,19 +1575,16 @@ Return the underlying metadata object.
-
-Implementation
+##### Implementation
public fun store_metadata<T: key>(store: Object<T>): Object<Metadata> acquires FungibleStore {
- borrow_store_resource(store).metadata
+ borrow_store_resource(&store).metadata
}
-
-
## Function `amount`
@@ -1176,8 +1597,7 @@ Return the amount
of a given fungible asset.
-
-Implementation
+##### Implementation
public fun amount(fa: &FungibleAsset): u64 {
@@ -1187,8 +1607,6 @@ Return the amount
of a given fungible asset.
-
-
## Function `balance`
@@ -1202,23 +1620,18 @@ Get the balance of a given store.
-
-Implementation
+##### Implementation
public fun balance<T: key>(store: Object<T>): u64 acquires FungibleStore {
- if (store_exists(object::object_address(store))) {
- borrow_store_resource(store).balance
- } else {
- 0
- }
+ if (store_exists(object::object_address(&store))) {
+ borrow_store_resource(&store).balance
+ } else { 0 }
}
-
-
## Function `is_frozen`
@@ -1234,18 +1647,156 @@ If the store has not been created, we default to returning false so deposits can
-
-Implementation
+##### Implementation
public fun is_frozen<T: key>(store: Object<T>): bool acquires FungibleStore {
- store_exists(object::object_address(store)) && borrow_store_resource(store).frozen
+ store_exists(object::object_address(&store))
+ && borrow_store_resource(&store).frozen
+}
+
+
+
+
+
+
+## Function `is_store_dispatchable`
+
+Return whether a fungible asset type is dispatchable.
+
+
+#[view]
+public fun is_store_dispatchable<T: key>(store: object::Object<T>): bool
+
+
+
+
+##### Implementation
+
+
+public fun is_store_dispatchable<T: key>(store: Object<T>): bool acquires FungibleStore {
+ let fa_store = borrow_store_resource(&store);
+ let metadata_addr = object::object_address(&fa_store.metadata);
+ exists<DispatchFunctionStore>(metadata_addr)
+}
+
+
+
+
+
+
+## Function `deposit_dispatch_function`
+
+
+
+public fun deposit_dispatch_function<T: key>(store: object::Object<T>): option::Option<function_info::FunctionInfo>
+
+
+
+
+##### Implementation
+
+
+public fun deposit_dispatch_function<T: key>(
+ store: Object<T>
+): Option<FunctionInfo> acquires FungibleStore, DispatchFunctionStore {
+ let fa_store = borrow_store_resource(&store);
+ let metadata_addr = object::object_address(&fa_store.metadata);
+ if (exists<DispatchFunctionStore>(metadata_addr)) {
+ borrow_global<DispatchFunctionStore>(metadata_addr).deposit_function
+ } else {
+ option::none()
+ }
+}
+
+
+
+
+
+
+## Function `withdraw_dispatch_function`
+
+
+
+public fun withdraw_dispatch_function<T: key>(store: object::Object<T>): option::Option<function_info::FunctionInfo>
+
+
+
+
+##### Implementation
+
+
+public fun withdraw_dispatch_function<T: key>(
+ store: Object<T>
+): Option<FunctionInfo> acquires FungibleStore, DispatchFunctionStore {
+ let fa_store = borrow_store_resource(&store);
+ let metadata_addr = object::object_address(&fa_store.metadata);
+ if (exists<DispatchFunctionStore>(metadata_addr)) {
+ borrow_global<DispatchFunctionStore>(metadata_addr).withdraw_function
+ } else {
+ option::none()
+ }
}
-
+
+
+## Function `derived_balance_dispatch_function`
+
+
+
+public(friend) fun derived_balance_dispatch_function<T: key>(store: object::Object<T>): option::Option<function_info::FunctionInfo>
+
+
+
+
+##### Implementation
+
+
+public(friend) fun derived_balance_dispatch_function<T: key>(
+ store: Object<T>
+): Option<FunctionInfo> acquires FungibleStore, DispatchFunctionStore {
+ let fa_store = borrow_store_resource(&store);
+ let metadata_addr = object::object_address(&fa_store.metadata);
+ if (exists<DispatchFunctionStore>(metadata_addr)) {
+ borrow_global<DispatchFunctionStore>(metadata_addr).derived_balance_function
+ } else {
+ option::none()
+ }
+}
+
+
+
+
+
+
+## Function `derived_supply_dispatch_function`
+
+
+
+public(friend) fun derived_supply_dispatch_function<T: key>(metadata: object::Object<T>): option::Option<function_info::FunctionInfo>
+
+
+
+
+##### Implementation
+
+
+public(friend) fun derived_supply_dispatch_function<T: key>(
+ metadata: Object<T>
+): Option<FunctionInfo> acquires DeriveSupply {
+ let metadata_addr = object::object_address(&metadata);
+ if (exists<DeriveSupply>(metadata_addr)) {
+ borrow_global<DeriveSupply>(metadata_addr).dispatch_function
+ } else {
+ option::none()
+ }
+}
+
+
+
@@ -1258,8 +1809,7 @@ If the store has not been created, we default to returning false so deposits can
-
-Implementation
+##### Implementation
public fun asset_metadata(fa: &FungibleAsset): Object<Metadata> {
@@ -1269,8 +1819,6 @@ If the store has not been created, we default to returning false so deposits can
-
-
## Function `mint_ref_metadata`
@@ -1283,8 +1831,7 @@ Get the underlying metadata object from the mint_ref_metadata(ref: &MintRef): Object<Metadata> {
@@ -1294,8 +1841,6 @@ Get the underlying metadata object from the
## Function `transfer_ref_metadata`
@@ -1308,8 +1853,7 @@ Get the underlying metadata object from the transfer_ref_metadata(ref: &TransferRef): Object<Metadata> {
@@ -1319,8 +1863,6 @@ Get the underlying metadata object from the
## Function `burn_ref_metadata`
@@ -1333,8 +1875,7 @@ Get the underlying metadata object from the burn_ref_metadata(ref: &BurnRef): Object<Metadata> {
@@ -1344,7 +1885,27 @@ Get the underlying metadata object from the
+
+## Function `object_from_metadata_ref`
+
+Get the underlying metadata object from the MutateMetadataRef
.
+
+
+public fun object_from_metadata_ref(ref: &fungible_asset::MutateMetadataRef): object::Object<fungible_asset::Metadata>
+
+
+
+
+##### Implementation
+
+
+public fun object_from_metadata_ref(ref: &MutateMetadataRef): Object<Metadata> {
+ ref.metadata
+}
+
+
+
@@ -1359,16 +1920,15 @@ Note: it does not move the underlying object.
-
-Implementation
+##### Implementation
public entry fun transfer<T: key>(
sender: &signer,
from: Object<T>,
to: Object<T>,
- amount: u64,
-) acquires FungibleStore {
+ amount: u64
+) acquires FungibleStore, DispatchFunctionStore {
let fa = withdraw(sender, from, amount);
deposit(to, fa);
}
@@ -1376,8 +1936,6 @@ Note: it does not move the underlying object.
-
-
## Function `create_store`
@@ -1391,20 +1949,17 @@ Applications can use this to create multiple stores for isolating fungible asset
-
-Implementation
+##### Implementation
public fun create_store<T: key>(
- constructor_ref: &ConstructorRef,
- metadata: Object<T>,
+ constructor_ref: &ConstructorRef, metadata: Object<T>
): Object<FungibleStore> {
let store_obj = &object::generate_signer(constructor_ref);
- move_to(store_obj, FungibleStore {
- metadata: object::convert(metadata),
- balance: 0,
- frozen: false,
- });
+ move_to(
+ store_obj,
+ FungibleStore { metadata: object::convert(metadata), balance: 0, frozen: false }
+ );
object::object_from_constructor_ref<FungibleStore>(constructor_ref)
}
@@ -1412,8 +1967,6 @@ Applications can use this to create multiple stores for isolating fungible asset
-
-
## Function `create_store_with_extend_ref`
@@ -1427,20 +1980,17 @@ Applications can use this to create multiple stores for isolating fungible asset
-
-Implementation
+##### Implementation
public fun create_store_with_extend_ref<T: key>(
- extend_ref: &ExtendRef,
- metadata: Object<T>,
+ extend_ref: &ExtendRef, metadata: Object<T>
): Object<FungibleStore> {
let store_obj = &object::generate_signer_for_extending(extend_ref);
- move_to(store_obj, FungibleStore {
- metadata: object::convert(metadata),
- balance: 0,
- frozen: false,
- });
+ move_to(
+ store_obj,
+ FungibleStore { metadata: object::convert(metadata), balance: 0, frozen: false }
+ );
let obj_addr = object::address_from_extend_ref(extend_ref);
object::address_to_object<FungibleStore>(obj_addr)
@@ -1449,8 +1999,6 @@ Applications can use this to create multiple stores for isolating fungible asset
-
-
## Function `remove_store`
@@ -1463,22 +2011,92 @@ Used to delete a store. Requires the store to be completely empty prior to remo
-
-Implementation
+##### Implementation
public fun remove_store(delete_ref: &DeleteRef) acquires FungibleStore {
let store = object::object_from_delete_ref<FungibleStore>(delete_ref);
- let addr = object::object_address(store);
- let FungibleStore { metadata: _, balance, frozen: _ }
- = move_from<FungibleStore>(addr);
- assert!(balance == 0, error::permission_denied(EBALANCE_IS_NOT_ZERO));
+ let addr = object::object_address(&store);
+ let FungibleStore { metadata: _, balance, frozen: _ } =
+ move_from<FungibleStore>(addr);
+ assert!(
+ balance == 0,
+ error::permission_denied(EBALANCE_IS_NOT_ZERO)
+ );
+}
+
+
+
+
+
+
+## Function `withdraw_sanity_check`
+
+Check the permission for withdraw operation.
+
+
+public(friend) fun withdraw_sanity_check<T: key>(owner: &signer, store: object::Object<T>, abort_on_dispatch: bool)
+
+
+
+
+##### Implementation
+
+
+public(friend) fun withdraw_sanity_check<T: key>(
+ owner: &signer, store: Object<T>, abort_on_dispatch: bool
+) acquires FungibleStore, DispatchFunctionStore {
+ assert!(
+ object::owns(store, signer::address_of(owner)),
+ error::permission_denied(ENOT_STORE_OWNER)
+ );
+ let fa_store = borrow_store_resource(&store);
+ assert!(
+ !abort_on_dispatch || !has_withdraw_dispatch_function(fa_store.metadata),
+ error::invalid_argument(EINVALID_DISPATCHABLE_OPERATIONS)
+ );
+ assert!(!fa_store.frozen, error::permission_denied(ESTORE_IS_FROZEN));
}
-
+
+
+## Function `deposit_sanity_check`
+
+Deposit amount
of the fungible asset to store
.
+
+
+public fun deposit_sanity_check<T: key>(store: object::Object<T>, abort_on_dispatch: bool)
+
+
+
+
+##### Implementation
+
+
+public fun deposit_sanity_check<T: key>(
+ store: Object<T>, abort_on_dispatch: bool
+) acquires FungibleStore, DispatchFunctionStore {
+ let fa_store = borrow_store_resource(&store);
+ assert!(
+ !abort_on_dispatch || !has_deposit_dispatch_function(fa_store.metadata),
+ error::invalid_argument(EINVALID_DISPATCHABLE_OPERATIONS)
+ );
+
+ assert!(!fa_store.frozen, error::permission_denied(ESTORE_IS_FROZEN));
+
+ // cannot deposit to blocked account
+ let store_addr = object::object_address(&store);
+ assert!(
+ !is_blocked_store_addr(store_addr),
+ error::invalid_argument(ECANNOT_DEPOSIT_TO_BLOCKED_ACCOUNT)
+ );
+}
+
+
+
@@ -1492,25 +2110,19 @@ Withdraw amount
of the fungible asset from store
by th
-
-Implementation
+##### Implementation
public fun withdraw<T: key>(
- owner: &signer,
- store: Object<T>,
- amount: u64,
-): FungibleAsset acquires FungibleStore {
- assert!(object::owns(store, signer::address_of(owner)), error::permission_denied(ENOT_STORE_OWNER));
- assert!(!is_frozen(store), error::invalid_argument(ESTORE_IS_FROZEN));
- withdraw_internal(object::object_address(store), amount)
+ owner: &signer, store: Object<T>, amount: u64
+): FungibleAsset acquires FungibleStore, DispatchFunctionStore {
+ withdraw_sanity_check(owner, store, true);
+ withdraw_internal(object::object_address(&store), amount)
}
-
-
## Function `deposit`
@@ -1523,20 +2135,19 @@ Deposit amount
of the fungible asset to store
.
-
-Implementation
+##### Implementation
-public fun deposit<T: key>(store: Object<T>, fa: FungibleAsset) acquires FungibleStore {
- assert!(!is_frozen(store), error::invalid_argument(ESTORE_IS_FROZEN));
- deposit_internal(store, fa);
+public fun deposit<T: key>(
+ store: Object<T>, fa: FungibleAsset
+) acquires FungibleStore, DispatchFunctionStore {
+ deposit_sanity_check(store, true);
+ deposit_internal(object::object_address(&store), fa);
}
-
-
## Function `mint`
@@ -1549,8 +2160,7 @@ Mint the specified amount
of the fungible asset.
-
-Implementation
+##### Implementation
public fun mint(ref: &MintRef, amount: u64): FungibleAsset acquires Supply {
@@ -1560,20 +2170,15 @@ Mint the specified amount
of the fungible asset.
increase_supply(metadata, amount);
// emit event
- let metadata_addr = object::object_address(metadata);
+ let metadata_addr = object::object_address(&metadata);
event::emit(MintEvent { metadata_addr, amount });
- FungibleAsset {
- metadata,
- amount
- }
+ FungibleAsset { metadata, amount }
}
-
-
## Function `mint_to`
@@ -1586,20 +2191,19 @@ Mint the specified amount
of the fungible asset to a destination st
-
-Implementation
+##### Implementation
-public fun mint_to<T: key>(ref: &MintRef, store: Object<T>, amount: u64)
-acquires FungibleStore, Supply {
- deposit(store, mint(ref, amount));
+public fun mint_to<T: key>(
+ ref: &MintRef, store: Object<T>, amount: u64
+) acquires FungibleStore, Supply, DispatchFunctionStore {
+ deposit_sanity_check(store, false);
+ deposit_internal(object::object_address(&store), mint(ref, amount));
}
-
-
## Function `set_frozen_flag`
@@ -1612,22 +2216,26 @@ Enable/disable a store's ability to do direct transfers of the fungible asset.
-
-Implementation
+##### Implementation
public fun set_frozen_flag<T: key>(
- ref: &TransferRef,
- store: Object<T>,
- frozen: bool,
+ ref: &TransferRef, store: Object<T>, frozen: bool
) acquires FungibleStore {
assert!(
ref.metadata == store_metadata(store),
- error::invalid_argument(ETRANSFER_REF_AND_STORE_MISMATCH),
+ error::invalid_argument(ETRANSFER_REF_AND_STORE_MISMATCH)
+ );
+
+ let metadata_addr = object::object_address(&ref.metadata);
+ let store_addr = object::object_address(&store);
+
+ // cannot freeze module account store
+ assert!(
+ !is_module_account_store_addr(store_addr),
+ error::invalid_argument(ECONNOT_MANIPULATE_MODULE_ACCOUNT_STORE)
);
- let metadata_addr = object::object_address(ref.metadata);
- let store_addr = object::object_address(store);
borrow_global_mut<FungibleStore>(store_addr).frozen = frozen;
// emit event
@@ -1637,8 +2245,6 @@ Enable/disable a store's ability to do direct transfers of the fungible asset.
-
-
## Function `burn`
@@ -1651,28 +2257,25 @@ Burns a fungible asset
-
-Implementation
+##### Implementation
public fun burn(ref: &BurnRef, fa: FungibleAsset) acquires Supply {
- let FungibleAsset {
- metadata,
- amount,
- } = fa;
- assert!(ref.metadata == metadata, error::invalid_argument(EBURN_REF_AND_FUNGIBLE_ASSET_MISMATCH));
+ let FungibleAsset { metadata, amount } = fa;
+ assert!(
+ ref.metadata == metadata,
+ error::invalid_argument(EBURN_REF_AND_FUNGIBLE_ASSET_MISMATCH)
+ );
decrease_supply(metadata, amount);
// emit event
- let metadata_addr = object::object_address(metadata);
+ let metadata_addr = object::object_address(&metadata);
event::emit(BurnEvent { metadata_addr, amount });
}
-
-
## Function `burn_from`
@@ -1685,27 +2288,32 @@ Burn the amount
of the fungible asset from the given store.
-
-Implementation
+##### Implementation
public fun burn_from<T: key>(
- ref: &BurnRef,
- store: Object<T>,
- amount: u64
+ ref: &BurnRef, store: Object<T>, amount: u64
) acquires FungibleStore, Supply {
let metadata = ref.metadata;
- assert!(metadata == store_metadata(store), error::invalid_argument(EBURN_REF_AND_STORE_MISMATCH));
+ assert!(
+ metadata == store_metadata(store),
+ error::invalid_argument(EBURN_REF_AND_STORE_MISMATCH)
+ );
+
+ let store_addr = object::object_address(&store);
+
+ // cannot burn module account funds
+ assert!(
+ !is_module_account_store_addr(store_addr),
+ error::invalid_argument(ECONNOT_MANIPULATE_MODULE_ACCOUNT_STORE)
+ );
- let store_addr = object::object_address(store);
burn(ref, withdraw_internal(store_addr, amount));
}
-
-
## Function `withdraw_with_ref`
@@ -1718,28 +2326,30 @@ Withdraw amount
of the fungible asset from the store
i
-
-Implementation
+##### Implementation
public fun withdraw_with_ref<T: key>(
- ref: &TransferRef,
- store: Object<T>,
- amount: u64
+ ref: &TransferRef, store: Object<T>, amount: u64
): FungibleAsset acquires FungibleStore {
assert!(
ref.metadata == store_metadata(store),
- error::invalid_argument(ETRANSFER_REF_AND_STORE_MISMATCH),
+ error::invalid_argument(ETRANSFER_REF_AND_STORE_MISMATCH)
);
- withdraw_internal(object::object_address(store), amount)
+ // cannot withdraw module account funds
+ let store_addr = object::object_address(&store);
+ assert!(
+ !is_module_account_store_addr(store_addr),
+ error::invalid_argument(ECONNOT_MANIPULATE_MODULE_ACCOUNT_STORE)
+ );
+
+ withdraw_internal(object::object_address(&store), amount)
}
-
-
## Function `deposit_with_ref`
@@ -1752,27 +2362,30 @@ Deposit the fungible asset into the store
ignoring frozen
-Implementation
+##### Implementation
public fun deposit_with_ref<T: key>(
- ref: &TransferRef,
- store: Object<T>,
- fa: FungibleAsset
+ ref: &TransferRef, store: Object<T>, fa: FungibleAsset
) acquires FungibleStore {
assert!(
ref.metadata == fa.metadata,
error::invalid_argument(ETRANSFER_REF_AND_FUNGIBLE_ASSET_MISMATCH)
);
- deposit_internal(store, fa);
+
+ // cannot deposit to blocked account
+ let store_addr = object::object_address(&store);
+ assert!(
+ !is_blocked_store_addr(store_addr),
+ error::invalid_argument(ECANNOT_DEPOSIT_TO_BLOCKED_ACCOUNT)
+ );
+
+ deposit_internal(object::object_address(&store), fa);
}
-
-
## Function `transfer_with_ref`
@@ -1785,15 +2398,14 @@ Transfer amount
of the fungible asset with transfer_with_ref<T: key>(
transfer_ref: &TransferRef,
from: Object<T>,
to: Object<T>,
- amount: u64,
+ amount: u64
) acquires FungibleStore {
let fa = withdraw_with_ref(transfer_ref, from, amount);
deposit_with_ref(transfer_ref, to, fa);
@@ -1802,341 +2414,292 @@ Transfer amount
of the fungible asset with
-
+## Function `mutate_metadata`
-## Function `zero`
-
-Create a fungible asset with zero amount.
-This can be useful when starting a series of computations where the initial value is 0.
+Mutate specified fields of the fungible asset's Metadata
.
-public fun zero<T: key>(metadata: object::Object<T>): fungible_asset::FungibleAsset
+public fun mutate_metadata(metadata_ref: &fungible_asset::MutateMetadataRef, name: option::Option<string::String>, symbol: option::Option<string::String>, decimals: option::Option<u8>, icon_uri: option::Option<string::String>, project_uri: option::Option<string::String>)
-
-Implementation
+##### Implementation
-public fun zero<T: key>(metadata: Object<T>): FungibleAsset {
- FungibleAsset {
- metadata: object::convert(metadata),
- amount: 0,
- }
+public fun mutate_metadata(
+ metadata_ref: &MutateMetadataRef,
+ name: Option<String>,
+ symbol: Option<String>,
+ decimals: Option<u8>,
+ icon_uri: Option<String>,
+ project_uri: Option<String>
+) acquires Metadata {
+ let metadata_address = object::object_address(&metadata_ref.metadata);
+ let mutable_metadata = borrow_global_mut<Metadata>(metadata_address);
+
+ if (option::is_some(&name)) {
+ mutable_metadata.name = option::extract(&mut name);
+ };
+ if (option::is_some(&symbol)) {
+ mutable_metadata.symbol = option::extract(&mut symbol);
+ };
+ if (option::is_some(&decimals)) {
+ mutable_metadata.decimals = option::extract(&mut decimals);
+ };
+ if (option::is_some(&icon_uri)) {
+ mutable_metadata.icon_uri = option::extract(&mut icon_uri);
+ };
+ if (option::is_some(&project_uri)) {
+ mutable_metadata.project_uri = option::extract(&mut project_uri);
+ };
}
-
+
-
+## Function `sudo_transfer`
-## Function `extract`
+Transfer an amount
of fungible asset from from_store
, which should be owned by sender
, to receiver
.
+Note: it does not move the underlying object.
-Extract a given amount from the given fungible asset and return a new one.
+This function is only callable by the chain.
-public fun extract(fungible_asset: &mut fungible_asset::FungibleAsset, amount: u64): fungible_asset::FungibleAsset
+public(friend) fun sudo_transfer<T: key>(sender: &signer, from: object::Object<T>, to: object::Object<T>, amount: u64)
-
-Implementation
+##### Implementation
-public fun extract(fungible_asset: &mut FungibleAsset, amount: u64): FungibleAsset {
- assert!(fungible_asset.amount >= amount, error::invalid_argument(EINSUFFICIENT_BALANCE));
- fungible_asset.amount = fungible_asset.amount - amount;
- FungibleAsset {
- metadata: fungible_asset.metadata,
- amount,
- }
+public(friend) fun sudo_transfer<T: key>(
+ sender: &signer,
+ from: Object<T>,
+ to: Object<T>,
+ amount: u64
+) acquires FungibleStore, DispatchFunctionStore {
+ let fa = withdraw(sender, from, amount);
+ sudo_deposit(to, fa);
}
-
+
-
+## Function `sudo_deposit`
-## Function `merge`
+Deposit amount
of the fungible asset to store
.
-"Merges" the two given fungible assets. The fungible asset passed in as dst_fungible_asset
will have a value
-equal to the sum of the two (dst_fungible_asset
and src_fungible_asset
).
+This function is only callable by the chain.
-public fun merge(dst_fungible_asset: &mut fungible_asset::FungibleAsset, src_fungible_asset: fungible_asset::FungibleAsset)
+public(friend) fun sudo_deposit<T: key>(store: object::Object<T>, fa: fungible_asset::FungibleAsset)
-
-Implementation
+##### Implementation
-public fun merge(dst_fungible_asset: &mut FungibleAsset, src_fungible_asset: FungibleAsset) {
- let FungibleAsset { metadata, amount } = src_fungible_asset;
- assert!(metadata == dst_fungible_asset.metadata, error::invalid_argument(EFUNGIBLE_ASSET_MISMATCH));
- dst_fungible_asset.amount = dst_fungible_asset.amount + amount;
+public(friend) fun sudo_deposit<T: key>(
+ store: Object<T>, fa: FungibleAsset
+) acquires FungibleStore {
+ assert!(
+ !is_frozen(store),
+ error::invalid_argument(ESTORE_IS_FROZEN)
+ );
+
+ deposit_internal(object::object_address(&store), fa);
}
-
-
-
+
-## Function `destroy_zero`
+## Function `zero`
-Destroy an empty fungible asset.
+Create a fungible asset with zero amount.
+This can be useful when starting a series of computations where the initial value is 0.
-public fun destroy_zero(fungible_asset: fungible_asset::FungibleAsset)
+public fun zero<T: key>(metadata: object::Object<T>): fungible_asset::FungibleAsset
-
-Implementation
+##### Implementation
-public fun destroy_zero(fungible_asset: FungibleAsset) {
- let FungibleAsset { amount, metadata: _ } = fungible_asset;
- assert!(amount == 0, error::invalid_argument(EAMOUNT_IS_NOT_ZERO));
+public fun zero<T: key>(metadata: Object<T>): FungibleAsset {
+ FungibleAsset { metadata: object::convert(metadata), amount: 0 }
}
-
-
-
+
-## Function `deposit_internal`
+## Function `extract`
+Extract a given amount from the given fungible asset and return a new one.
-fun deposit_internal<T: key>(store: object::Object<T>, fa: fungible_asset::FungibleAsset)
+public fun extract(fungible_asset: &mut fungible_asset::FungibleAsset, amount: u64): fungible_asset::FungibleAsset
-
-Implementation
-
-
-fun deposit_internal<T: key>(store: Object<T>, fa: FungibleAsset) acquires FungibleStore {
- let FungibleAsset { metadata, amount } = fa;
- if (amount == 0) return;
-
- let store_metadata = store_metadata(store);
- assert!(metadata == store_metadata, error::invalid_argument(EFUNGIBLE_ASSET_AND_STORE_MISMATCH));
- let metadata_addr = object::object_address(store_metadata);
- let store_addr = object::object_address(store);
- let store = borrow_global_mut<FungibleStore>(store_addr);
- store.balance = store.balance + amount;
+##### Implementation
- // emit event
- event::emit(DepositEvent { store_addr, metadata_addr, amount });
+public fun extract(fungible_asset: &mut FungibleAsset, amount: u64): FungibleAsset {
+ assert!(
+ fungible_asset.amount >= amount,
+ error::invalid_argument(EINSUFFICIENT_BALANCE)
+ );
+ fungible_asset.amount = fungible_asset.amount - amount;
+ FungibleAsset { metadata: fungible_asset.metadata, amount }
}
-
-
-
+
-## Function `withdraw_internal`
+## Function `merge`
-Extract amount
of the fungible asset from store
.
+"Merges" the two given fungible assets. The fungible asset passed in as dst_fungible_asset
will have a value
+equal to the sum of the two (dst_fungible_asset
and src_fungible_asset
).
-fun withdraw_internal(store_addr: address, amount: u64): fungible_asset::FungibleAsset
+public fun merge(dst_fungible_asset: &mut fungible_asset::FungibleAsset, src_fungible_asset: fungible_asset::FungibleAsset)
-
-Implementation
+##### Implementation
-fun withdraw_internal(
- store_addr: address,
- amount: u64,
-): FungibleAsset acquires FungibleStore {
- let store = borrow_global_mut<FungibleStore>(store_addr);
- let metadata = store.metadata;
- if (amount == 0) return zero(metadata);
-
- assert!(store.balance >= amount, error::invalid_argument(EINSUFFICIENT_BALANCE));
- store.balance = store.balance - amount;
-
- // emit event
- let metadata_addr = object::object_address(metadata);
- event::emit(WithdrawEvent { store_addr, metadata_addr, amount });
-
- FungibleAsset { metadata, amount }
+public fun merge(
+ dst_fungible_asset: &mut FungibleAsset, src_fungible_asset: FungibleAsset
+) {
+ let FungibleAsset { metadata, amount } = src_fungible_asset;
+ assert!(
+ metadata == dst_fungible_asset.metadata,
+ error::invalid_argument(EFUNGIBLE_ASSET_MISMATCH)
+ );
+ dst_fungible_asset.amount = dst_fungible_asset.amount + amount;
}
-
-
-
+
-## Function `increase_supply`
+## Function `destroy_zero`
-Increase the supply of a fungible asset by minting.
+Destroy an empty fungible asset.
-fun increase_supply<T: key>(metadata: object::Object<T>, amount: u64)
+public fun destroy_zero(fungible_asset: fungible_asset::FungibleAsset)
-
-Implementation
-
+##### Implementation
-fun increase_supply<T: key>(metadata: Object<T>, amount: u64) acquires Supply {
- if (amount == 0) return;
- let metadata_address = object::object_address(metadata);
- assert!(exists<Supply>(metadata_address), error::not_found(ESUPPLY_NOT_FOUND));
- let supply = borrow_global_mut<Supply>(metadata_address);
- if (option::is_some(&supply.maximum)) {
- let max = *option::borrow_mut(&mut supply.maximum);
- assert!(
- max - supply.current >= (amount as u128),
- error::out_of_range(EMAX_SUPPLY_EXCEEDED)
- )
- };
- supply.current = supply.current + (amount as u128);
+public fun destroy_zero(fungible_asset: FungibleAsset) {
+ let FungibleAsset { amount, metadata: _ } = fungible_asset;
+ assert!(
+ amount == 0,
+ error::invalid_argument(EAMOUNT_IS_NOT_ZERO)
+ );
}
-
-
-
+
-## Function `decrease_supply`
+## Function `deposit_internal`
-Decrease the supply of a fungible asset by burning.
-fun decrease_supply<T: key>(metadata: object::Object<T>, amount: u64)
+public(friend) fun deposit_internal(store_addr: address, fa: fungible_asset::FungibleAsset)
-
-Implementation
-
+##### Implementation
-fun decrease_supply<T: key>(metadata: Object<T>, amount: u64) acquires Supply {
- if (amount == 0) return;
- let metadata_address = object::object_address(metadata);
- assert!(exists<Supply>(metadata_address), error::not_found(ESUPPLY_NOT_FOUND));
- let supply = borrow_global_mut<Supply>(metadata_address);
+public(friend) fun deposit_internal(
+ store_addr: address, fa: FungibleAsset
+) acquires FungibleStore {
+ let FungibleAsset { metadata, amount } = fa;
assert!(
- supply.current >= (amount as u128),
- error::invalid_state(ESUPPLY_UNDERFLOW)
+ exists<FungibleStore>(store_addr),
+ error::not_found(EFUNGIBLE_STORE_EXISTENCE)
+ );
+ let store = borrow_global_mut<FungibleStore>(store_addr);
+ assert!(
+ metadata == store.metadata,
+ error::invalid_argument(EFUNGIBLE_ASSET_AND_STORE_MISMATCH)
);
- supply.current = supply.current - (amount as u128);
-}
-
-
-
-
-
-
-
-
-## Function `borrow_fungible_metadata`
-
-
-
-fun borrow_fungible_metadata<T: key>(metadata: object::Object<T>): &fungible_asset::Metadata
-
-
-
-
-Implementation
+ if (amount == 0) return;
+ store.balance = store.balance + amount;
-inline fun borrow_fungible_metadata<T: key>(
- metadata: Object<T>
-): &Metadata acquires Metadata {
- let addr = object::object_address(metadata);
- borrow_global<Metadata>(addr)
+ // emit event
+ let metadata_addr = object::object_address(&metadata);
+ event::emit(DepositEvent { store_addr, metadata_addr, amount });
}
-
-
-
-
-## Function `borrow_fungible_metadata_mut`
-
-
-
-fun borrow_fungible_metadata_mut<T: key>(metadata: object::Object<T>): &mut fungible_asset::Metadata
-
-
+
+## Function `withdraw_internal`
-
-Implementation
+Extract amount
of the fungible asset from store
.
-inline fun borrow_fungible_metadata_mut<T: key>(
- metadata: Object<T>
-): &mut Metadata acquires Metadata {
- let addr = object::object_address(metadata);
- borrow_global_mut<Metadata>(addr)
-}
+public(friend) fun withdraw_internal(store_addr: address, amount: u64): fungible_asset::FungibleAsset
-
-
-
-
-## Function `borrow_store_resource`
-
-
-
-fun borrow_store_resource<T: key>(store: object::Object<T>): &fungible_asset::FungibleStore
-
+##### Implementation
+public(friend) fun withdraw_internal(
+ store_addr: address, amount: u64
+): FungibleAsset acquires FungibleStore {
+ let store = borrow_global_mut<FungibleStore>(store_addr);
+ let metadata = store.metadata;
+ if (amount == 0) return zero(metadata);
-
-Implementation
+ assert!(
+ store.balance >= amount,
+ error::invalid_argument(EINSUFFICIENT_BALANCE)
+ );
+ store.balance = store.balance - amount;
+ // emit event
+ let metadata_addr = object::object_address(&metadata);
+ event::emit(WithdrawEvent { store_addr, metadata_addr, amount });
-inline fun borrow_store_resource<T: key>(store: Object<T>): &FungibleStore acquires FungibleStore {
- borrow_global<FungibleStore>(object::object_address(store))
+ FungibleAsset { metadata, amount }
}
-
-
-
-
diff --git a/initia_stdlib/doc/hex.md b/initia_stdlib/doc/hex.md
index a598eef..348ce33 100644
--- a/initia_stdlib/doc/hex.md
+++ b/initia_stdlib/doc/hex.md
@@ -5,13 +5,55 @@
+- [Constants](#@Constants_0)
- [Function `encode_to_string`](#0x1_hex_encode_to_string)
+- [Function `encode_to_string_with_option`](#0x1_hex_encode_to_string_with_option)
- [Function `decode_string`](#0x1_hex_decode_string)
-- [Function `encode_to_char`](#0x1_hex_encode_to_char)
-- [Function `decode_char`](#0x1_hex_decode_char)
-use 0x1::string;
+use 0x1::error;
+use 0x1::string;
+
+
+
+
+
+
+## Constants
+
+
+
+
+
+
+const ENOT_HEXSTRING: u64 = 1;
+
+
+
+
+
+
+
+
+const LOWERA: u8 = 97;
+
+
+
+
+
+
+
+
+const UPPERA: u8 = 65;
+
+
+
+
+
+
+
+
+const ZERO: u8 = 48;
@@ -27,15 +69,14 @@
-
-Implementation
+##### Implementation
public fun encode_to_string(bz: &vector<u8>): String {
let vec: vector<u8> = vector[];
let len = vector::length(bz);
let index = 0;
- while(index < len) {
+ while (index < len) {
let val = *vector::borrow(bz, index);
let h = val / 0x10;
let l = val % 0x10;
@@ -50,110 +91,88 @@
-
+
-
-
-## Function `decode_string`
+## Function `encode_to_string_with_option`
-public fun decode_string(str: &string::String): vector<u8>
+public fun encode_to_string_with_option(bz: &vector<u8>, is_upper: bool): string::String
-
-Implementation
+##### Implementation
-public fun decode_string(str: &String): vector<u8> {
+public fun encode_to_string_with_option(
+ bz: &vector<u8>, is_upper: bool
+): String {
let vec: vector<u8> = vector[];
-
- let bz = string::bytes(str);
let len = vector::length(bz);
- if (len == 0) {
- return vec
- };
-
- let index = if (len % 2 == 1) {
- let l = decode_char(*vector::borrow(bz, 0));
- vector::push_back(&mut vec, l);
-
- 1
- } else {
- 0
- };
-
- while(index < len) {
- let h = decode_char(*vector::borrow(bz, index));
- let l = decode_char(*vector::borrow(bz, index+1));
-
- vector::push_back(&mut vec, l + (h << 4));
-
- index = index + 2
+ let index = 0;
+ while (index < len) {
+ let val = *vector::borrow(bz, index);
+ vector::push_back(
+ &mut vec,
+ encode_to_char_with_option(val / 0x10, is_upper)
+ );
+ vector::push_back(
+ &mut vec,
+ encode_to_char_with_option(val % 0x10, is_upper)
+ );
+ index = index + 1;
};
- vec
+ string::utf8(vec)
}
-
-
-
-
-## Function `encode_to_char`
-
-
-
-fun encode_to_char(num: u8): u8
-
-
+
+## Function `decode_string`
-
-Implementation
-fun encode_to_char(num: u8): u8 {
- if (num < 10) {
- 0x30 + num
- } else {
- 0x57 + num
- }
-}
+public fun decode_string(str: &string::String): vector<u8>
-
-
-
-
-## Function `decode_char`
+##### Implementation
+public fun decode_string(str: &String): vector<u8> {
+ assert!(
+ is_hex_string(str),
+ error::invalid_argument(ENOT_HEXSTRING)
+ );
-fun decode_char(num: u8): u8
-
+ let vec: vector<u8> = vector[];
+ let bz = string::bytes(str);
+ let len = vector::length(bz);
+ if (len == 0) {
+ return vec
+ };
+ let index =
+ if (len % 2 == 1) {
+ let l = decode_char(*vector::borrow(bz, 0));
+ vector::push_back(&mut vec, l);
+ 1
+ } else { 0 };
-
-Implementation
+ while (index < len) {
+ let h = decode_char(*vector::borrow(bz, index));
+ let l = decode_char(*vector::borrow(bz, index + 1));
+ vector::push_back(&mut vec, (h << 4) + l);
+ index = index + 2
+ };
-fun decode_char(num: u8): u8 {
- if (num < 0x3a) {
- num - 0x30
- } else {
- num - 0x57
- }
+ vec
}
-
-
-
-
diff --git a/initia_stdlib/doc/initia_nft.md b/initia_stdlib/doc/initia_nft.md
index fcbe35d..ccac1b7 100644
--- a/initia_stdlib/doc/initia_nft.md
+++ b/initia_stdlib/doc/initia_nft.md
@@ -21,30 +21,24 @@ The key features are:
- [Function `create_collection_object`](#0x1_initia_nft_create_collection_object)
- [Function `mint`](#0x1_initia_nft_mint)
- [Function `mint_nft_object`](#0x1_initia_nft_mint_nft_object)
-- [Function `mint_internal`](#0x1_initia_nft_mint_internal)
-- [Function `borrow`](#0x1_initia_nft_borrow)
- [Function `is_mutable_description`](#0x1_initia_nft_is_mutable_description)
- [Function `is_mutable_uri`](#0x1_initia_nft_is_mutable_uri)
-- [Function `authorized_borrow`](#0x1_initia_nft_authorized_borrow)
- [Function `burn`](#0x1_initia_nft_burn)
- [Function `set_description`](#0x1_initia_nft_set_description)
- [Function `set_uri`](#0x1_initia_nft_set_uri)
-- [Function `collection_object`](#0x1_initia_nft_collection_object)
-- [Function `borrow_collection`](#0x1_initia_nft_borrow_collection)
- [Function `is_mutable_collection_description`](#0x1_initia_nft_is_mutable_collection_description)
- [Function `is_mutable_collection_royalty`](#0x1_initia_nft_is_mutable_collection_royalty)
- [Function `is_mutable_collection_uri`](#0x1_initia_nft_is_mutable_collection_uri)
- [Function `is_mutable_collection_nft_description`](#0x1_initia_nft_is_mutable_collection_nft_description)
- [Function `is_mutable_collection_nft_uri`](#0x1_initia_nft_is_mutable_collection_nft_uri)
-- [Function `authorized_borrow_collection`](#0x1_initia_nft_authorized_borrow_collection)
- [Function `set_collection_description`](#0x1_initia_nft_set_collection_description)
- [Function `set_collection_royalties`](#0x1_initia_nft_set_collection_royalties)
- [Function `set_collection_royalties_call`](#0x1_initia_nft_set_collection_royalties_call)
- [Function `set_collection_uri`](#0x1_initia_nft_set_collection_uri)
-use 0x1::collection;
-use 0x1::decimal128;
+use 0x1::bigdecimal;
+use 0x1::collection;
use 0x1::error;
use 0x1::nft;
use 0x1::object;
@@ -68,8 +62,7 @@ Storage state for managing the no-code Collection.
-
-Fields
+##### Fields
@@ -112,8 +105,6 @@ Storage state for managing the no-code Collection.
-
-
## Resource `InitiaNft`
@@ -126,8 +117,7 @@ Storage state for managing the no-code Nft.
-
-Fields
+##### Fields
@@ -146,8 +136,6 @@ Storage state for managing the no-code Nft.
-
-
## Constants
@@ -220,13 +208,12 @@ The provided signer is not the owner
Create a new collection
-public entry fun create_collection(creator: &signer, description: string::String, max_supply: option::Option<u64>, name: string::String, uri: string::String, mutable_description: bool, mutable_royalty: bool, mutable_uri: bool, mutable_nft_description: bool, mutable_nft_uri: bool, royalty: decimal128::Decimal128)
+public entry fun create_collection(creator: &signer, description: string::String, max_supply: option::Option<u64>, name: string::String, uri: string::String, mutable_description: bool, mutable_royalty: bool, mutable_uri: bool, mutable_nft_description: bool, mutable_nft_uri: bool, royalty: bigdecimal::BigDecimal)
-
-Implementation
+##### Implementation
public entry fun create_collection(
@@ -240,7 +227,7 @@ Create a new collection
mutable_uri: bool,
mutable_nft_description: bool,
mutable_nft_uri: bool,
- royalty: Decimal128,
+ royalty: BigDecimal
) {
create_collection_object(
creator,
@@ -253,28 +240,25 @@ Create a new collection
mutable_uri,
mutable_nft_description,
mutable_nft_uri,
- royalty,
+ royalty
);
}
-
-
## Function `create_collection_object`
-public fun create_collection_object(creator: &signer, description: string::String, max_supply: option::Option<u64>, name: string::String, uri: string::String, mutable_description: bool, mutable_royalty: bool, mutable_uri: bool, mutable_nft_description: bool, mutable_nft_uri: bool, royalty: decimal128::Decimal128): (object::Object<initia_nft::InitiaNftCollection>, object::ExtendRef)
+public fun create_collection_object(creator: &signer, description: string::String, max_supply: option::Option<u64>, name: string::String, uri: string::String, mutable_description: bool, mutable_royalty: bool, mutable_uri: bool, mutable_nft_description: bool, mutable_nft_uri: bool, royalty: bigdecimal::BigDecimal): (object::Object<initia_nft::InitiaNftCollection>, object::ExtendRef)
-
-Implementation
+##### Implementation
public fun create_collection_object(
@@ -288,41 +272,48 @@ Create a new collection
mutable_uri: bool,
mutable_nft_description: bool,
mutable_nft_uri: bool,
- royalty: Decimal128,
+ royalty: BigDecimal
): (Object<InitiaNftCollection>, ExtendRef) {
let creator_addr = signer::address_of(creator);
let royalty = royalty::create(royalty, creator_addr);
- let constructor_ref = if (option::is_some(&max_supply)) {
- collection::create_fixed_collection(
- creator,
- description,
- option::extract(&mut max_supply),
- name,
- option::some(royalty),
- uri,
- )
- } else {
- collection::create_unlimited_collection(
- creator,
- description,
- name,
- option::some(royalty),
- uri,
- )
- };
+ let constructor_ref =
+ if (option::is_some(&max_supply)) {
+ collection::create_fixed_collection(
+ creator,
+ description,
+ option::extract(&mut max_supply),
+ name,
+ option::some(royalty),
+ uri
+ )
+ } else {
+ collection::create_unlimited_collection(
+ creator,
+ description,
+ name,
+ option::some(royalty),
+ uri
+ )
+ };
let object_signer = object::generate_signer(&constructor_ref);
- let mutator_ref = if (mutable_description || mutable_uri) {
- option::some(collection::generate_mutator_ref(&constructor_ref))
- } else {
- option::none()
- };
-
- let royalty_mutator_ref = if (mutable_royalty) {
- option::some(royalty::generate_mutator_ref(object::generate_extend_ref(&constructor_ref)))
- } else {
- option::none()
- };
+ let mutator_ref =
+ if (mutable_description || mutable_uri) {
+ option::some(collection::generate_mutator_ref(&constructor_ref))
+ } else {
+ option::none()
+ };
+
+ let royalty_mutator_ref =
+ if (mutable_royalty) {
+ option::some(
+ royalty::generate_mutator_ref(
+ object::generate_extend_ref(&constructor_ref)
+ )
+ )
+ } else {
+ option::none()
+ };
let extend_ref = object::generate_extend_ref(&constructor_ref);
@@ -332,7 +323,7 @@ Create a new collection
mutable_description,
mutable_uri,
mutable_nft_description,
- mutable_nft_uri,
+ mutable_nft_uri
};
move_to(&object_signer, initia_nft_collection);
(object::object_from_constructor_ref(&constructor_ref), extend_ref)
@@ -341,8 +332,6 @@ Create a new collection
-
-
## Function `mint`
@@ -355,8 +344,7 @@ With an existing collection, directly mint a viable nft into the creators accoun
-
-Implementation
+##### Implementation
public entry fun mint(
@@ -366,19 +354,29 @@ With an existing collection, directly mint a viable nft into the creators accoun
token_id: String,
uri: String,
can_burn: bool,
- to: Option<address>,
+ to: Option<address>
) acquires InitiaNftCollection {
- let (nft_object, _) = mint_nft_object(creator, collection, description, token_id, uri, can_burn);
+ let (nft_object, _) =
+ mint_nft_object(
+ creator,
+ collection,
+ description,
+ token_id,
+ uri,
+ can_burn
+ );
if (option::is_some(&to)) {
- object::transfer(creator, nft_object, option::extract(&mut to));
+ object::transfer(
+ creator,
+ nft_object,
+ option::extract(&mut to)
+ );
}
}
-
-
## Function `mint_nft_object`
@@ -391,8 +389,7 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-Implementation
+##### Implementation
public fun mint_nft_object(
@@ -401,121 +398,25 @@ Mint a nft into an existing collection, and retrieve the object / address of the
description: String,
token_id: String,
uri: String,
- can_burn: bool,
+ can_burn: bool
): (Object<InitiaNft>, ExtendRef) acquires InitiaNftCollection {
- let constructor_ref = mint_internal(
- creator,
- collection,
- description,
- token_id,
- uri,
- can_burn,
- );
- let extend_ref = object::generate_extend_ref(&constructor_ref);
-
- (object::object_from_constructor_ref(&constructor_ref), extend_ref)
-}
-
-
-
-
-
-
-
-
-## Function `mint_internal`
-
-
-
-fun mint_internal(creator: &signer, collection: string::String, description: string::String, token_id: string::String, uri: string::String, can_burn: bool): object::ConstructorRef
-
-
-
-
-
-Implementation
-
-
-fun mint_internal(
- creator: &signer,
- collection: String,
- description: String,
- token_id: String,
- uri: String,
- can_burn: bool,
-): ConstructorRef acquires InitiaNftCollection {
- let constructor_ref = nft::create(
+ let constructor_ref =
+ mint_internal(
creator,
collection,
description,
token_id,
- option::none(),
uri,
+ can_burn
);
+ let extend_ref = object::generate_extend_ref(&constructor_ref);
- let object_signer = object::generate_signer(&constructor_ref);
-
- let collection_obj = collection_object(creator, &collection);
- let collection = borrow_collection(collection_obj);
-
- let mutator_ref = if (
- collection.mutable_nft_description
- || collection.mutable_nft_uri
- ) {
- option::some(nft::generate_mutator_ref(&constructor_ref))
- } else {
- option::none()
- };
-
- let burn_ref = if (can_burn) {
- option::some(nft::generate_burn_ref(&constructor_ref))
- } else {
- option::none()
- };
-
- let initia_nft = InitiaNft {
- burn_ref,
- mutator_ref,
- };
- move_to(&object_signer, initia_nft);
-
- constructor_ref
-}
-
-
-
-
-
-
-
-
-## Function `borrow`
-
-
-
-fun borrow<T: key>(nft: object::Object<T>): &initia_nft::InitiaNft
-
-
-
-
-
-Implementation
-
-
-inline fun borrow<T: key>(nft: Object<T>): &InitiaNft {
- let nft_address = object::object_address(nft);
- assert!(
- exists<InitiaNft>(nft_address),
- error::not_found(ENFT_DOES_NOT_EXIST),
- );
- borrow_global<InitiaNft>(nft_address)
+ (object::object_from_constructor_ref(&constructor_ref), extend_ref)
}
-
-
## Function `is_mutable_description`
@@ -528,8 +429,7 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-Implementation
+##### Implementation
public fun is_mutable_description<T: key>(nft: Object<T>): bool acquires InitiaNftCollection {
@@ -539,8 +439,6 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-
## Function `is_mutable_uri`
@@ -553,8 +451,7 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-Implementation
+##### Implementation
public fun is_mutable_uri<T: key>(nft: Object<T>): bool acquires InitiaNftCollection {
@@ -564,42 +461,6 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-
-
-
-## Function `authorized_borrow`
-
-
-
-fun authorized_borrow<T: key>(nft: object::Object<T>, creator: &signer): &initia_nft::InitiaNft
-
-
-
-
-
-Implementation
-
-
-inline fun authorized_borrow<T: key>(nft: Object<T>, creator: &signer): &InitiaNft {
- let nft_address = object::object_address(nft);
- assert!(
- exists<InitiaNft>(nft_address),
- error::not_found(ENFT_DOES_NOT_EXIST),
- );
-
- assert!(
- nft::creator(nft) == signer::address_of(creator),
- error::permission_denied(ENOT_CREATOR),
- );
- borrow_global<InitiaNft>(nft_address)
-}
-
-
-
-
-
-
## Function `burn`
@@ -611,35 +472,32 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-Implementation
+##### Implementation
public entry fun burn<T: key>(owner: &signer, nft: Object<T>) acquires InitiaNft {
- let nft_address = object::object_address(nft);
+ let nft_address = object::object_address(&nft);
assert!(
exists<InitiaNft>(nft_address),
- error::not_found(ENFT_DOES_NOT_EXIST),
+ error::not_found(ENFT_DOES_NOT_EXIST)
);
assert!(
object::owns(nft, signer::address_of(owner)),
- error::permission_denied(ENOT_OWNER),
+ error::permission_denied(ENOT_OWNER)
);
- let initia_nft = move_from<InitiaNft>(object::object_address(nft));
- assert!(option::is_some(&initia_nft.burn_ref), error::invalid_state(ECAN_NOT_BURN));
- let InitiaNft {
- burn_ref,
- mutator_ref: _,
- } = initia_nft;
+ let initia_nft = move_from<InitiaNft>(object::object_address(&nft));
+ assert!(
+ option::is_some(&initia_nft.burn_ref),
+ error::invalid_state(ECAN_NOT_BURN)
+ );
+ let InitiaNft { burn_ref, mutator_ref: _ } = initia_nft;
nft::burn(option::extract(&mut burn_ref));
}
-
-
## Function `set_description`
@@ -651,28 +509,26 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-Implementation
+##### Implementation
public entry fun set_description<T: key>(
- creator: &signer,
- nft: Object<T>,
- description: String,
+ creator: &signer, nft: Object<T>, description: String
) acquires InitiaNftCollection, InitiaNft {
assert!(
is_mutable_description(nft),
- error::permission_denied(EFIELD_NOT_MUTABLE),
+ error::permission_denied(EFIELD_NOT_MUTABLE)
);
let initia_nft = authorized_borrow(nft, creator);
- nft::set_description(option::borrow(&initia_nft.mutator_ref), description);
+ nft::set_description(
+ option::borrow(&initia_nft.mutator_ref),
+ description
+ );
}
-
-
## Function `set_uri`
@@ -684,18 +540,15 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-Implementation
+##### Implementation
public entry fun set_uri<T: key>(
- creator: &signer,
- nft: Object<T>,
- uri: String,
+ creator: &signer, nft: Object<T>, uri: String
) acquires InitiaNftCollection, InitiaNft {
assert!(
is_mutable_uri(nft),
- error::permission_denied(EFIELD_NOT_MUTABLE),
+ error::permission_denied(EFIELD_NOT_MUTABLE)
);
let initia_nft = authorized_borrow(nft, creator);
nft::set_uri(option::borrow(&initia_nft.mutator_ref), uri);
@@ -704,62 +557,6 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-
-
-
-## Function `collection_object`
-
-
-
-fun collection_object(creator: &signer, name: &string::String): object::Object<initia_nft::InitiaNftCollection>
-
-
-
-
-
-Implementation
-
-
-inline fun collection_object(creator: &signer, name: &String): Object<InitiaNftCollection> {
- let collection_addr = collection::create_collection_address(signer::address_of(creator), name);
- object::address_to_object<InitiaNftCollection>(collection_addr)
-}
-
-
-
-
-
-
-
-
-## Function `borrow_collection`
-
-
-
-fun borrow_collection<T: key>(nft: object::Object<T>): &initia_nft::InitiaNftCollection
-
-
-
-
-
-Implementation
-
-
-inline fun borrow_collection<T: key>(nft: Object<T>): &InitiaNftCollection {
- let collection_address = object::object_address(nft);
- assert!(
- exists<InitiaNftCollection>(collection_address),
- error::not_found(ECOLLECTION_DOES_NOT_EXIST),
- );
- borrow_global<InitiaNftCollection>(collection_address)
-}
-
-
-
-
-
-
## Function `is_mutable_collection_description`
@@ -771,12 +568,11 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-Implementation
+##### Implementation
public fun is_mutable_collection_description<T: key>(
- collection: Object<T>,
+ collection: Object<T>
): bool acquires InitiaNftCollection {
borrow_collection(collection).mutable_description
}
@@ -784,8 +580,6 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-
## Function `is_mutable_collection_royalty`
@@ -797,12 +591,11 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-Implementation
+##### Implementation
public fun is_mutable_collection_royalty<T: key>(
- collection: Object<T>,
+ collection: Object<T>
): bool acquires InitiaNftCollection {
option::is_some(&borrow_collection(collection).royalty_mutator_ref)
}
@@ -810,8 +603,6 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-
## Function `is_mutable_collection_uri`
@@ -823,12 +614,11 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-Implementation
+##### Implementation
public fun is_mutable_collection_uri<T: key>(
- collection: Object<T>,
+ collection: Object<T>
): bool acquires InitiaNftCollection {
borrow_collection(collection).mutable_uri
}
@@ -836,8 +626,6 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-
## Function `is_mutable_collection_nft_description`
@@ -849,12 +637,11 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-Implementation
+##### Implementation
public fun is_mutable_collection_nft_description<T: key>(
- collection: Object<T>,
+ collection: Object<T>
): bool acquires InitiaNftCollection {
borrow_collection(collection).mutable_nft_description
}
@@ -862,8 +649,6 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-
## Function `is_mutable_collection_nft_uri`
@@ -875,12 +660,11 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-Implementation
+##### Implementation
public fun is_mutable_collection_nft_uri<T: key>(
- collection: Object<T>,
+ collection: Object<T>
): bool acquires InitiaNftCollection {
borrow_collection(collection).mutable_nft_uri
}
@@ -888,41 +672,6 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-
-
-
-## Function `authorized_borrow_collection`
-
-
-
-fun authorized_borrow_collection<T: key>(collection: object::Object<T>, creator: &signer): &initia_nft::InitiaNftCollection
-
-
-
-
-
-Implementation
-
-
-inline fun authorized_borrow_collection<T: key>(collection: Object<T>, creator: &signer): &InitiaNftCollection {
- let collection_address = object::object_address(collection);
- assert!(
- exists<InitiaNftCollection>(collection_address),
- error::not_found(ECOLLECTION_DOES_NOT_EXIST),
- );
- assert!(
- collection::creator(collection) == signer::address_of(creator),
- error::permission_denied(ENOT_CREATOR),
- );
- borrow_global<InitiaNftCollection>(collection_address)
-}
-
-
-
-
-
-
## Function `set_collection_description`
@@ -934,28 +683,26 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-Implementation
+##### Implementation
public entry fun set_collection_description<T: key>(
- creator: &signer,
- collection: Object<T>,
- description: String,
+ creator: &signer, collection: Object<T>, description: String
) acquires InitiaNftCollection {
let initia_nft_collection = authorized_borrow_collection(collection, creator);
assert!(
initia_nft_collection.mutable_description,
- error::permission_denied(EFIELD_NOT_MUTABLE),
+ error::permission_denied(EFIELD_NOT_MUTABLE)
+ );
+ collection::set_description(
+ option::borrow(&initia_nft_collection.mutator_ref),
+ description
);
- collection::set_description(option::borrow(&initia_nft_collection.mutator_ref), description);
}
-
-
## Function `set_collection_royalties`
@@ -967,48 +714,45 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-Implementation
+##### Implementation
public fun set_collection_royalties<T: key>(
- creator: &signer,
- collection: Object<T>,
- royalty: royalty::Royalty,
+ creator: &signer, collection: Object<T>, royalty: royalty::Royalty
) acquires InitiaNftCollection {
let initia_nft_collection = authorized_borrow_collection(collection, creator);
assert!(
option::is_some(&initia_nft_collection.royalty_mutator_ref),
- error::permission_denied(EFIELD_NOT_MUTABLE),
+ error::permission_denied(EFIELD_NOT_MUTABLE)
+ );
+ royalty::update(
+ option::borrow(&initia_nft_collection.royalty_mutator_ref),
+ royalty
);
- royalty::update(option::borrow(&initia_nft_collection.royalty_mutator_ref), royalty);
}
-
-
## Function `set_collection_royalties_call`
-public fun set_collection_royalties_call<T: key>(creator: &signer, collection: object::Object<T>, royalty: decimal128::Decimal128, payee_address: address)
+public fun set_collection_royalties_call<T: key>(creator: &signer, collection: object::Object<T>, royalty: bigdecimal::BigDecimal, payee_address: address)
-
-Implementation
+##### Implementation
public fun set_collection_royalties_call<T: key>(
creator: &signer,
collection: Object<T>,
- royalty: Decimal128,
- payee_address: address,
+ royalty: BigDecimal,
+ payee_address: address
) acquires InitiaNftCollection {
let royalty = royalty::create(royalty, payee_address);
set_collection_royalties(creator, collection, royalty);
@@ -1017,8 +761,6 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-
## Function `set_collection_uri`
@@ -1030,24 +772,20 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-Implementation
+##### Implementation
public entry fun set_collection_uri<T: key>(
- creator: &signer,
- collection: Object<T>,
- uri: String,
+ creator: &signer, collection: Object<T>, uri: String
) acquires InitiaNftCollection {
let initia_nft_collection = authorized_borrow_collection(collection, creator);
assert!(
initia_nft_collection.mutable_uri,
- error::permission_denied(EFIELD_NOT_MUTABLE),
+ error::permission_denied(EFIELD_NOT_MUTABLE)
+ );
+ collection::set_uri(
+ option::borrow(&initia_nft_collection.mutator_ref),
+ uri
);
- collection::set_uri(option::borrow(&initia_nft_collection.mutator_ref), uri);
}
-
-
-
-
diff --git a/initia_stdlib/doc/json.md b/initia_stdlib/doc/json.md
index 39789ce..9d4de2a 100644
--- a/initia_stdlib/doc/json.md
+++ b/initia_stdlib/doc/json.md
@@ -5,2027 +5,79 @@
-- [Struct `JsonIndex`](#0x1_json_JsonIndex)
-- [Struct `JsonElem`](#0x1_json_JsonElem)
-- [Struct `JsonObject`](#0x1_json_JsonObject)
-- [Struct `Number`](#0x1_json_Number)
-- [Struct `JsonValue`](#0x1_json_JsonValue)
-- [Struct `NativeArrayValue`](#0x1_json_NativeArrayValue)
-- [Struct `NativeObjectValue`](#0x1_json_NativeObjectValue)
-- [Struct `KeyValue`](#0x1_json_KeyValue)
-- [Constants](#@Constants_0)
-- [Function `empty`](#0x1_json_empty)
-- [Function `data`](#0x1_json_data)
-- [Function `stringify`](#0x1_json_stringify)
-- [Function `stringify_internal`](#0x1_json_stringify_internal)
-- [Function `parse`](#0x1_json_parse)
-- [Function `parse_internal`](#0x1_json_parse_internal)
-- [Function `start_index`](#0x1_json_start_index)
-- [Function `get_next_index`](#0x1_json_get_next_index)
-- [Function `get_prev_index`](#0x1_json_get_prev_index)
-- [Function `get_index_last`](#0x1_json_get_index_last)
-- [Function `get_depth`](#0x1_json_get_depth)
-- [Function `borrow`](#0x1_json_borrow)
-- [Function `borrow_mut`](#0x1_json_borrow_mut)
-- [Function `find`](#0x1_json_find)
-- [Function `is_null_index`](#0x1_json_is_null_index)
-- [Function `set_elem`](#0x1_json_set_elem)
-- [Function `set_bool`](#0x1_json_set_bool)
-- [Function `set_number`](#0x1_json_set_number)
-- [Function `set_int_raw`](#0x1_json_set_int_raw)
-- [Function `set_int_string`](#0x1_json_set_int_string)
-- [Function `set_dec_string`](#0x1_json_set_dec_string)
-- [Function `set_string`](#0x1_json_set_string)
-- [Function `set_array`](#0x1_json_set_array)
-- [Function `set_object`](#0x1_json_set_object)
-- [Function `new_bool`](#0x1_json_new_bool)
-- [Function `new_number`](#0x1_json_new_number)
-- [Function `new_int`](#0x1_json_new_int)
-- [Function `new_dec`](#0x1_json_new_dec)
-- [Function `new_string`](#0x1_json_new_string)
-- [Function `new_array`](#0x1_json_new_array)
-- [Function `new_object`](#0x1_json_new_object)
-- [Function `is_null`](#0x1_json_is_null)
-- [Function `is_bool`](#0x1_json_is_bool)
-- [Function `is_number`](#0x1_json_is_number)
-- [Function `is_string`](#0x1_json_is_string)
-- [Function `is_array`](#0x1_json_is_array)
-- [Function `is_object`](#0x1_json_is_object)
-- [Function `as_bool`](#0x1_json_as_bool)
-- [Function `as_number`](#0x1_json_as_number)
-- [Function `as_int`](#0x1_json_as_int)
-- [Function `as_dec`](#0x1_json_as_dec)
-- [Function `as_string`](#0x1_json_as_string)
-- [Function `unpack_elem`](#0x1_json_unpack_elem)
-- [Function `get_child_length`](#0x1_json_get_child_length)
-- [Function `set_child_length`](#0x1_json_set_child_length)
-- [Function `get_type`](#0x1_json_get_type)
-- [Function `parse_bool`](#0x1_json_parse_bool)
-- [Function `parse_number`](#0x1_json_parse_number)
-- [Function `parse_string`](#0x1_json_parse_string)
-- [Function `parse_array`](#0x1_json_parse_array)
-- [Function `parse_object`](#0x1_json_parse_object)
-- [Function `stringify_bool`](#0x1_json_stringify_bool)
-- [Function `stringify_number`](#0x1_json_stringify_number)
-- [Function `stringify_string`](#0x1_json_stringify_string)
-- [Function `stringify_array`](#0x1_json_stringify_array)
-- [Function `stringify_object`](#0x1_json_stringify_object)
+- [Function `marshal`](#0x1_json_marshal)
+- [Function `marshal_to_string`](#0x1_json_marshal_to_string)
+- [Function `unmarshal`](#0x1_json_unmarshal)
-use 0x1::decimal256;
-use 0x1::error;
-use 0x1::option;
-use 0x1::simple_map;
-use 0x1::string;
-use 0x1::vector;
+use 0x1::string;
-
+
-## Struct `JsonIndex`
+## Function `marshal`
+Marshal data to JSON bytes.
+NOTE: key _type_
is converted to @type
+NOTE: key _move_
is converted to move
-struct JsonIndex has copy, drop, store
-
-
-
-
-
-Fields
-
-
-
--
-
data: vector<u64>
-
--
-
-
-
-
-
-
-
-
-
-## Struct `JsonElem`
-
-
-
-struct JsonElem has copy, drop, store
-
-
-
-
-
-Fields
-
-
-
--
-
key: option::Option<string::String>
-
--
-
-
--
-
value: json::JsonValue
-
--
-
-
-
-
-
-
-
-
-
-## Struct `JsonObject`
-
-
-
-struct JsonObject has copy, drop
-
-
-
-
-
-Fields
-
-
-
--
-
data: simple_map::SimpleMap<json::JsonIndex, json::JsonElem>
-
--
-
-
-
-
-
-
-
-
-
-## Struct `Number`
-
-
-
-struct Number has copy, drop, store
-
-
-
-
-
-Fields
-
-
-
--
-
type: u8
-
--
-
-
--
-
value: u256
-
--
-
-
--
-
is_positive: bool
-
--
-
-
-
-
-
-
-
-
-
-## Struct `JsonValue`
-
-
-
-struct JsonValue has copy, drop, store
-
-
-
-
-
-Fields
-
-
-
--
-
type: u8
-
--
-
-
--
-
value_bool: option::Option<bool>
-
--
-
-
--
-
value_number: option::Option<json::Number>
-
--
-
-
--
-
value_string: option::Option<string::String>
-
--
-
-
--
-
child_length: u64
-
--
-
-
-
-
-
-
-
-
-
-## Struct `NativeArrayValue`
-
-
-
-struct NativeArrayValue has copy, drop, store
-
-
-
-
-
-Fields
-
-
-
--
-
type: u8
-
--
-
-
--
-
value: string::String
-
--
-
-
-
-
-
-
-
-
-
-## Struct `NativeObjectValue`
-
-
-
-struct NativeObjectValue has copy, drop, store
-
-
-
-
-
-Fields
-
-
-
--
-
type: u8
-
--
-
-
--
-
key: string::String
-
--
-
-
--
-
value: string::String
-
--
-
-
-
-
-
-
-
-
-
-## Struct `KeyValue`
-
-
-
-struct KeyValue has copy, drop, store
-
-
-
-
-
-Fields
-
-
-
--
-
key: string::String
-
--
-
-
--
-
value: string::String
-
--
-
-
-
-
-
-
-
-
-
-## Constants
-
-
-
-
-
-
-const EKEY_NOT_FOUND: u64 = 7;
-
-
-
-
-
-
-
-
-const EOUT_OF_RANGE: u64 = 3;
-
-
-
-
-
-
-
-
-const EDUPLICATED_INDEX: u64 = 5;
-
-
-
-
-
-
-
-
-const EINVALID_ARGS: u64 = 2;
-
-
-
-
-
-
-
-
-const ENOT_SUPPORTED_TYPE: u64 = 6;
-
-
-
-
-
-
-
-
-const ESERDE_DESERIALIZE: u64 = 1;
-
-
-
-
-
-
-
-
-const ETYPE_MISMATCH: u64 = 4;
-
-
-
-
-
-
-
-
-const JSON_VALUE_TYPE_ARRAY: u8 = 4;
-
-
-
-
-
-
-
-
-const JSON_VALUE_TYPE_BOOL: u8 = 1;
-
-
-
-
-
-
-
-
-const JSON_VALUE_TYPE_NULL: u8 = 0;
-
-
-
-
-
-
-
-
-const JSON_VALUE_TYPE_NUMBER: u8 = 2;
-
-
-
-
-
-
-
-
-const JSON_VALUE_TYPE_OBJECT: u8 = 5;
-
-
-
-
-
-
-
-
-const JSON_VALUE_TYPE_STRING: u8 = 3;
-
-
-
-
-
-
-
-
-const JSON_VALUE_TYPE_UNKNOWN: u8 = 255;
-
-
-
-
-
-
-
-
-const NUMBER_TYPE_DEC: u8 = 1;
-
-
-
-
-
-
-
-
-const NUMBER_TYPE_INT: u8 = 0;
-
-
-
-
-
-
-## Function `empty`
-
-
-
-public fun empty(): json::JsonObject
-
-
-
-
-
-Implementation
-
-
-public fun empty(): JsonObject{
- JsonObject {
- data: simple_map::create<JsonIndex, JsonElem>(),
- }
-}
-
-
-
-
-
-
-
-
-## Function `data`
-
-
-
-public fun data(json_obj: &json::JsonObject): &simple_map::SimpleMap<json::JsonIndex, json::JsonElem>
-
-
-
-
-
-Implementation
-
-
-public fun data(json_obj: &JsonObject): &SimpleMap<JsonIndex, JsonElem>{
- &json_obj.data
-}
-
-
-
-
-
-
-
-
-## Function `stringify`
-
-
-
-public fun stringify(json_obj: &json::JsonObject): string::String
-
-
-
-
-
-Implementation
-
-
-public fun stringify(json_obj: &JsonObject): String {
- let index = start_index();
- let (_, json_string) = stringify_internal(json_obj, index);
- json_string
-}
-
-
-
-
-
-
-
-
-## Function `stringify_internal`
-
-
-
-fun stringify_internal(json_obj: &json::JsonObject, current_index: json::JsonIndex): (option::Option<string::String>, string::String)
-
-
-
-
-
-Implementation
-
-
-fun stringify_internal(json_obj: &JsonObject, current_index: JsonIndex): (Option<String>, String) {
- let json_elem = borrow(json_obj, ¤t_index);
- let type = json_elem.value.type;
-
- assert!(type != JSON_VALUE_TYPE_NULL, ENOT_SUPPORTED_TYPE);
-
- if(type == JSON_VALUE_TYPE_BOOL) {
- (json_elem.key, stringify_bool(as_bool(json_elem.value)))
- } else if(type == JSON_VALUE_TYPE_NUMBER) {
- (json_elem.key, stringify_number(as_number(json_elem.value)))
- } else if(type == JSON_VALUE_TYPE_STRING) {
- (json_elem.key, stringify_string(as_string(json_elem.value)))
- } else if(type == JSON_VALUE_TYPE_ARRAY) {
- let values = vector::empty<String>();
- let i =0;
- while(i < json_elem.value.child_length) {
- let next_index = get_next_index(¤t_index, i);
- let (_, value) = stringify_internal(json_obj, next_index);
- vector::push_back(&mut values, value);
- i = i + 1;
- };
- (json_elem.key, stringify_array(values))
- } else if(type == JSON_VALUE_TYPE_OBJECT) {
- let values = vector::empty<KeyValue>();
- let i =0;
- while(i < json_elem.value.child_length) {
- let next_index = get_next_index(¤t_index, i);
- let (key, value) = stringify_internal(json_obj, next_index);
- vector::push_back(&mut values, KeyValue{
- key: *option::borrow(&key),
- value: value,
- });
- i = i + 1;
- };
- (json_elem.key, stringify_object(values))
- } else {
- abort(ENOT_SUPPORTED_TYPE)
- }
-}
-
-
-
-
-
-
-
-
-## Function `parse`
-
-
-
-public fun parse(json_string: string::String): json::JsonObject
-
-
-
-
-
-Implementation
-
-
-public fun parse(json_string: String): JsonObject {
- let json_obj = empty();
- let index = start_index();
- let type = get_type(&json_string);
- parse_internal(&mut json_obj, type, option::none<String>(),json_string, index);
-
- json_obj
-}
-
-
-
-
-
-
-
-
-## Function `parse_internal`
-
-
-
-fun parse_internal(json_obj: &mut json::JsonObject, type: u8, key: option::Option<string::String>, json_string: string::String, current_index: json::JsonIndex)
-
-
-
-
-
-Implementation
-
-
-fun parse_internal(json_obj: &mut JsonObject, type: u8, key: Option<String>, json_string: String, current_index: JsonIndex) {
- assert!(type != JSON_VALUE_TYPE_NULL, ENOT_SUPPORTED_TYPE);
-
- if(type == JSON_VALUE_TYPE_BOOL) {
- set_bool(json_obj, current_index, key, parse_bool(json_string));
- } else if(type == JSON_VALUE_TYPE_NUMBER) {
- set_number(json_obj, current_index, key, parse_number(json_string));
- } else if(type == JSON_VALUE_TYPE_STRING) {
- let string_value = parse_string(json_string);
- // number can be wrapped into string (e.g. "\"12.3456\"" -> "12.3456")
- let type = get_type(&string_value);
- if(type == JSON_VALUE_TYPE_NUMBER){
- set_number(json_obj, current_index, key, parse_number(string_value));
- } else {
- set_string(json_obj, current_index, key, string_value);
- }
- } else if(type == JSON_VALUE_TYPE_ARRAY) {
- let value = parse_array(json_string);
- vector::reverse(&mut value);
- let len = vector::length(&value);
-
- set_array(json_obj, current_index, key, len);
-
- let i = 0;
- while( i < len) {
- let array_value = vector::pop_back(&mut value);
- let index = get_next_index(¤t_index, i);
- parse_internal(json_obj, array_value.type, option::none<String>(), array_value.value, index);
- i = i + 1;
- };
- } else if(type == JSON_VALUE_TYPE_OBJECT) {
- let value = parse_object(json_string);
- vector::reverse(&mut value);
- let len = vector::length(&value);
-
- set_object(json_obj, current_index, key, len);
-
- let i = 0;
- while( i < len) {
- let object_value = vector::pop_back(&mut value);
- let index = get_next_index(¤t_index, i);
- parse_internal(json_obj, object_value.type, option::some(object_value.key), object_value.value, index);
- i = i + 1;
- };
- } else {
- abort(ENOT_SUPPORTED_TYPE)
- };
-}
-
-
-
-
-
-
-
-
-## Function `start_index`
-
-
-
-public fun start_index(): json::JsonIndex
-
-
-
-
-
-Implementation
-
-
-public fun start_index(): JsonIndex {
- JsonIndex {
- data: vector::singleton<u64>(0)
- }
-}
-
-
-
-
-
-
-
-
-## Function `get_next_index`
-
-
-
-public fun get_next_index(current: &json::JsonIndex, idx: u64): json::JsonIndex
-
-
-
-
-
-Implementation
-
-
-public fun get_next_index(current: &JsonIndex, idx: u64): JsonIndex {
- let index = *current;
- vector::push_back(&mut index.data, idx);
- index
-}
-
-
-
-
-
-
-
-
-## Function `get_prev_index`
-
-
-
-public fun get_prev_index(current: &json::JsonIndex): (json::JsonIndex, u64)
-
-
-
-
-
-Implementation
-
-
-public fun get_prev_index(current: &JsonIndex): (JsonIndex, u64) {
- let index = *current;
- let last = vector::pop_back(&mut index.data);
- (index, last)
-}
-
-
-
-
-
-
-
-
-## Function `get_index_last`
-
-
-
-public fun get_index_last(index: &json::JsonIndex): u64
-
-
-
-
-
-Implementation
-
-
-public fun get_index_last(index: &JsonIndex): u64 {
- let length = vector::length(&index.data);
- *vector::borrow(&index.data, length-1)
-}
-
-
-
-
-
-
-
-
-## Function `get_depth`
-
-
-
-public fun get_depth(index: &json::JsonIndex): u64
-
-
-
-
-
-Implementation
-
-
-public fun get_depth(index: &JsonIndex): u64 {
- vector::length(&index.data)
-}
-
-
-
-
-
-
-
-
-## Function `borrow`
-
-
-
-public fun borrow(obj: &json::JsonObject, index: &json::JsonIndex): &json::JsonElem
-
-
-
-
-
-Implementation
-
-
-public fun borrow(obj: &JsonObject, index: &JsonIndex): &JsonElem{
- simple_map::borrow(&obj.data, index)
-}
-
-
-
-
-
-
-
-
-## Function `borrow_mut`
-
-
-
-public fun borrow_mut(obj: &mut json::JsonObject, index: &json::JsonIndex): &mut json::JsonElem
-
-
-
-
-
-Implementation
-
-
-public fun borrow_mut(obj: &mut JsonObject, index: &JsonIndex): &mut JsonElem{
- simple_map::borrow_mut(&mut obj.data, index)
-}
-
-
-
-
-
-
-
-
-## Function `find`
-
-
-
-public fun find(obj: &json::JsonObject, index: &json::JsonIndex, key: &string::String): json::JsonIndex
-
-
-
-
-
-Implementation
-
-
-public fun find(obj: &JsonObject, index: &JsonIndex, key: &String): JsonIndex {
- let i = 0;
- let elem = borrow(obj, index);
-
- while (i < elem.value.child_length) {
- let next_index = get_next_index(index, i);
- let child_elem = borrow(obj, &next_index);
- if ( *string::bytes(option::borrow(&child_elem.key)) == *string::bytes(key)) {
- break
- };
- i = i + 1;
- };
-
- if( i >= elem.value.child_length) {
- JsonIndex {
- data: vector::empty(),
- }
- } else {
- get_next_index(index, i)
- }
-}
-
-
-
-
-
-
-
-
-## Function `is_null_index`
-
-
-
-public fun is_null_index(index: &json::JsonIndex): bool
-
-
-
-
-
-Implementation
-
-
-public fun is_null_index(index: &JsonIndex): bool {
- if( vector::length(&index.data) == 0) {
- true
- } else {
- false
- }
-}
-
-
-
-
-
-
-
-
-## Function `set_elem`
-
-
-
-fun set_elem(object: &mut json::JsonObject, index: json::JsonIndex, elem: json::JsonElem)
-
-
-
-
-
-Implementation
-
-
-fun set_elem(object: &mut JsonObject, index: JsonIndex, elem: JsonElem) {
- assert!(!simple_map::contains_key(&object.data, &index), EDUPLICATED_INDEX);
- simple_map::add(&mut object.data, index, elem);
-}
-
-
-
-
-
-
-
-
-## Function `set_bool`
-
-
-
-public fun set_bool(object: &mut json::JsonObject, index: json::JsonIndex, key: option::Option<string::String>, value: bool)
-
-
-
-
-
-Implementation
-
-
-public fun set_bool(object: &mut JsonObject, index: JsonIndex, key: Option<String>, value: bool) {
- set_elem(object, index, JsonElem {
- key: key,
- value: new_bool(value),
- });
-}
-
-
-
-
-
-
-
-
-## Function `set_number`
-
-
-
-fun set_number(object: &mut json::JsonObject, index: json::JsonIndex, key: option::Option<string::String>, value: json::Number)
-
-
-
-
-
-Implementation
-
-
-fun set_number(object: &mut JsonObject, index: JsonIndex, key: Option<String>, value: Number) {
- set_elem(object, index, JsonElem {
- key: key,
- value: new_number(value),
- });
-}
-
-
-
-
-
-
-
-
-## Function `set_int_raw`
-
-
-
-public fun set_int_raw(object: &mut json::JsonObject, index: json::JsonIndex, key: option::Option<string::String>, is_positive: bool, value: u256)
-
-
-
-
-
-Implementation
-
-
-public fun set_int_raw(object:&mut JsonObject, index: JsonIndex, key: Option<String>, is_positive: bool, value: u256) {
- set_elem(object, index, JsonElem {
- key: key,
- value: new_int(is_positive, value),
- });
-}
-
-
-
-
-
-
-
-
-## Function `set_int_string`
-
-
-
-public fun set_int_string(object: &mut json::JsonObject, index: json::JsonIndex, key: option::Option<string::String>, is_positive: bool, value: u256)
-
-
-
-
-
-Implementation
-
-
-public fun set_int_string(object:&mut JsonObject, index: JsonIndex, key: Option<String>, is_positive: bool, value: u256) {
- let int_number = new_int(is_positive, value);
- let int_string = stringify_number(as_number(int_number));
-
- set_elem(object, index, JsonElem {
- key: key,
- value: new_string(int_string),
- });
-}
-
-
-
-
-
-
-
-
-## Function `set_dec_string`
-
-
-
-public fun set_dec_string(object: &mut json::JsonObject, index: json::JsonIndex, key: option::Option<string::String>, is_positive: bool, value: decimal256::Decimal256)
-
-
-
-
-
-Implementation
-
-
-public fun set_dec_string(object:&mut JsonObject, index: JsonIndex, key: Option<String>, is_positive: bool, value: Decimal256) {
- let dec_number = new_dec(is_positive, value);
- let dec_string = stringify_number(as_number(dec_number));
-
- set_elem(object, index, JsonElem {
- key: key,
- value: new_string(dec_string),
- });
-}
-
-
-
-
-
-
-
-
-## Function `set_string`
-
-
-
-public fun set_string(object: &mut json::JsonObject, index: json::JsonIndex, key: option::Option<string::String>, value: string::String)
-
-
-
-
-
-Implementation
-
-
-public fun set_string(object: &mut JsonObject, index: JsonIndex, key: Option<String>, value: String) {
- set_elem(object, index, JsonElem {
- key: key,
- value: new_string(value),
- });
-}
-
-
-
-
-
-
-
-
-## Function `set_array`
-
-
-
-public fun set_array(object: &mut json::JsonObject, index: json::JsonIndex, key: option::Option<string::String>, child_length: u64)
-
-
-
-
-
-Implementation
-
-
-public fun set_array(object: &mut JsonObject, index: JsonIndex, key: Option<String>, child_length: u64) {
- set_elem(object, index, JsonElem {
- key: key,
- value: new_array(child_length),
- });
-}
-
-
-
-
-
-
-
-
-## Function `set_object`
-
-
-
-public fun set_object(object: &mut json::JsonObject, index: json::JsonIndex, key: option::Option<string::String>, child_length: u64)
-
-
-
-
-
-Implementation
-
-
-public fun set_object(object: &mut JsonObject, index: JsonIndex, key: Option<String>, child_length: u64) {
- set_elem(object, index, JsonElem {
- key: key,
- value: new_object(child_length),
- });
-}
-
-
-
-
-
-
-
-
-## Function `new_bool`
-
-
-
-public fun new_bool(value: bool): json::JsonValue
-
-
-
-
-
-Implementation
-
-
-public fun new_bool(value: bool): JsonValue {
- JsonValue {
- type: JSON_VALUE_TYPE_BOOL,
- value_bool: option::some<bool>(value),
- value_number: option::none<Number>(),
- value_string: option::none<String>(),
- child_length: 0,
- }
-}
-
-
-
-
-
-
-
-
-## Function `new_number`
-
-
-
-fun new_number(value: json::Number): json::JsonValue
-
-
-
-
-
-Implementation
-
-
-fun new_number(value: Number): JsonValue {
- JsonValue {
- type: JSON_VALUE_TYPE_NUMBER,
- value_bool: option::none<bool>(),
- value_number: option::some<Number>(value),
- value_string: option::none<String>(),
- child_length: 0,
- }
-}
-
-
-
-
-
-
-
-
-## Function `new_int`
-
-
-
-public fun new_int(is_positive: bool, value: u256): json::JsonValue
-
-
-
-
-
-Implementation
-
-
-public fun new_int(is_positive: bool, value:u256): JsonValue {
- new_number(Number {
- type: NUMBER_TYPE_INT,
- value: value,
- is_positive,
- })
-}
-
-
-
-
-
-
-
-
-## Function `new_dec`
-
-
-
-public fun new_dec(is_positive: bool, value: decimal256::Decimal256): json::JsonValue
-
-
-
-
-
-Implementation
-
-
-public fun new_dec(is_positive: bool, value:Decimal256): JsonValue {
- new_number(Number {
- type: NUMBER_TYPE_DEC,
- value: decimal256::val(&value),
- is_positive,
- })
-}
-
-
-
-
-
-
-
-
-## Function `new_string`
-
-
-
-public fun new_string(value: string::String): json::JsonValue
-
-
-
-
-
-Implementation
-
-
-public fun new_string(value: String): JsonValue {
- JsonValue {
- type: JSON_VALUE_TYPE_STRING,
- value_bool: option::none<bool>(),
- value_number: option::none<Number>(),
- value_string: option::some<String>(value),
- child_length: 0,
- }
-}
-
-
-
-
-
-
-
-
-## Function `new_array`
-
-
-
-public fun new_array(length: u64): json::JsonValue
-
-
-
-
-
-Implementation
-
-
-public fun new_array(length: u64): JsonValue {
- JsonValue {
- type: JSON_VALUE_TYPE_ARRAY,
- value_bool: option::none<bool>(),
- value_number: option::none<Number>(),
- value_string: option::none<String>(),
- child_length: length,
- }
-}
-
-
-
-
-
-
-
-
-## Function `new_object`
-
-
-
-public fun new_object(length: u64): json::JsonValue
-
-
-
-
-
-Implementation
-
-
-public fun new_object(length: u64): JsonValue {
- JsonValue {
- type: JSON_VALUE_TYPE_OBJECT,
- value_bool: option::none<bool>(),
- value_number: option::none<Number>(),
- value_string: option::none<String>(),
- child_length: length,
- }
-}
-
-
-
-
-
-
-
-
-## Function `is_null`
-
-
-
-public fun is_null(json_string: &string::String): bool
-
-
-
-
-
-Implementation
-
-
-public fun is_null(json_string: &String): bool {
- get_type(json_string) == JSON_VALUE_TYPE_NULL
-}
-
-
-
-
-
-
-
-
-## Function `is_bool`
-
-
-
-public fun is_bool(json_string: &string::String): bool
-
-
-
-
-
-Implementation
-
-
-public fun is_bool(json_string: &String): bool {
- get_type(json_string) == JSON_VALUE_TYPE_BOOL
-}
-
-
-
-
-
-
-
-
-## Function `is_number`
-
-
-
-public fun is_number(json_string: &string::String): bool
-
-
-
-
-
-Implementation
-
-
-public fun is_number(json_string: &String): bool {
- get_type(json_string) == JSON_VALUE_TYPE_NUMBER
-}
-
-
-
-
-
-
-
-
-## Function `is_string`
-
-
-
-public fun is_string(json_string: &string::String): bool
-
-
-
-
-
-Implementation
-
-
-public fun is_string(json_string: &String): bool {
- get_type(json_string) == JSON_VALUE_TYPE_STRING
-}
-
-
-
-
-
-
-
-
-## Function `is_array`
-
-
-
-public fun is_array(json_string: &string::String): bool
-
-
-
-
-
-Implementation
-
-
-public fun is_array(json_string: &String): bool {
- get_type(json_string) == JSON_VALUE_TYPE_ARRAY
-}
-
-
-
-
-
-
-
-
-## Function `is_object`
-
-
-
-public fun is_object(json_string: &string::String): bool
-
-
-
-
-Implementation
-
-
-public fun is_object(json_string: &String): bool {
- get_type(json_string) == JSON_VALUE_TYPE_OBJECT
-}
-
-
-
-
-
-
-
-
-## Function `as_bool`
-
-
-
-public fun as_bool(json_value: json::JsonValue): bool
-
-
-
-
-
-Implementation
-
-
-public fun as_bool(json_value: JsonValue): bool {
- assert!(json_value.type == JSON_VALUE_TYPE_BOOL, ETYPE_MISMATCH);
- *option::borrow(&json_value.value_bool)
-}
-
-
-
-
-
-
-
-
-## Function `as_number`
-
-
-
-fun as_number(json_value: json::JsonValue): json::Number
-
-
-
-
-
-Implementation
-
-
-fun as_number(json_value: JsonValue): Number {
- assert!(json_value.type == JSON_VALUE_TYPE_NUMBER, ETYPE_MISMATCH);
- *option::borrow(&json_value.value_number)
-}
-
-
-
-
-
-
-
-
-## Function `as_int`
-
-
-
-public fun as_int(json_value: json::JsonValue): (bool, u256)
-
-
-
-
-
-Implementation
-
-
-public fun as_int(json_value: JsonValue): (bool, u256) {// (signed, abs_val)
- let number = as_number(json_value);
- assert!(number.type == NUMBER_TYPE_INT, error::invalid_argument(ETYPE_MISMATCH));
- (number.is_positive, number.value)
-}
-
-
-
-
-
-
-
-
-## Function `as_dec`
-
-
-
-public fun as_dec(json_value: json::JsonValue): (bool, decimal256::Decimal256)
-
-
-
-
-
-Implementation
-
-
-public fun as_dec(json_value: JsonValue): (bool, Decimal256) {// (signed, abs_val)
- let number = as_number(json_value);
- assert!(number.type == NUMBER_TYPE_DEC, error::invalid_argument(ETYPE_MISMATCH));
- (number.is_positive, decimal256::new(number.value))
-}
-
-
-
-
-
-
-
-
-## Function `as_string`
-
-
-
-public fun as_string(json_value: json::JsonValue): string::String
-
-
-
-
-
-Implementation
-
-
-public fun as_string(json_value: JsonValue): String {
- assert!(json_value.type == JSON_VALUE_TYPE_STRING, ETYPE_MISMATCH);
- *option::borrow(&json_value.value_string)
-}
-
-
-
-
-
-
-
-
-## Function `unpack_elem`
-
-
-
-public fun unpack_elem(elem: &json::JsonElem): (option::Option<string::String>, json::JsonValue)
-
-
-
-
-
-Implementation
-
-
-public fun unpack_elem(elem: &JsonElem): (Option<String>, JsonValue) {
- (elem.key, elem.value)
-}
-
-
-
-
-
-
-
-
-## Function `get_child_length`
-
-
-
-public(friend) fun get_child_length(elem: &json::JsonElem): u64
-
-
-
-
-
-Implementation
-
-
-public(friend) fun get_child_length(elem: &JsonElem): u64 {
- elem.value.child_length
-}
-
-
-
-
-
-
-
-
-## Function `set_child_length`
-
-
-
-public(friend) fun set_child_length(elem: &mut json::JsonElem, length: u64)
-
-
-
-
-
-Implementation
-
-
-public(friend) fun set_child_length(elem: &mut JsonElem, length: u64) {
- elem.value.child_length = length;
-}
-
-
-
-
-
-
-
-
-## Function `get_type`
-
-
-
-public fun get_type(value: &string::String): u8
-
-
-
-
-
-Implementation
-
-
-public native fun get_type(value: &String): u8;
-
-
-
-
-
-
-
-
-## Function `parse_bool`
-
-
-
-fun parse_bool(value: string::String): bool
-
-
-
-
-
-Implementation
-
-
-native fun parse_bool(value: String): bool;
-
-
-
-
-
-
-
-
-## Function `parse_number`
-
-
-
-fun parse_number(value: string::String): json::Number
-
-
-
-
-
-Implementation
-
-
-native fun parse_number(value: String): Number;
-
-
-
-
-
-
-
-
-## Function `parse_string`
-
-
-
-fun parse_string(value: string::String): string::String
-
-
-
-
-
-Implementation
-
-
-native fun parse_string(value: String): String;
-
-
-
-
-
-
-
-
-## Function `parse_array`
-
-
-
-fun parse_array(value: string::String): vector<json::NativeArrayValue>
-
-
-
-
-
-Implementation
-
-
-native fun parse_array(value: String): vector<NativeArrayValue>;
-
-
-
-
-
-
-
-
-## Function `parse_object`
-
-
-
-fun parse_object(value: string::String): vector<json::NativeObjectValue>
-
-
-
-
-
-Implementation
-
-
-native fun parse_object(value: String): vector<NativeObjectValue>;
-
-
-
-
-
-
-
-
-## Function `stringify_bool`
-
-
-
-fun stringify_bool(value: bool): string::String
-
-
-
-
-
-Implementation
-
-
-native fun stringify_bool(value: bool): String;
-
-
-
-
-
-
-
-
-## Function `stringify_number`
-
-
-
-fun stringify_number(value: json::Number): string::String
-
-
-
-
-
-Implementation
-
-
-native fun stringify_number(value: Number): String;
-
-
-
-
-
-
-
-
-## Function `stringify_string`
-
-
-
-fun stringify_string(value: string::String): string::String
+public fun marshal<T: drop>(value: &T): vector<u8>
-
-Implementation
+##### Implementation
-native fun stringify_string(value: String): String;
+native public fun marshal<T: drop>(value: &T): vector<u8>;
-
+
-
+## Function `marshal_to_string`
-## Function `stringify_array`
+Marshal data to JSON string.
+NOTE: key _type_
is converted to @type
+NOTE: key _move_
is converted to move
-fun stringify_array(value: vector<string::String>): string::String
+public fun marshal_to_string<T: drop>(value: &T): string::String
-
-Implementation
+##### Implementation
-native fun stringify_array(value: vector<String>): String;
+native public fun marshal_to_string<T: drop>(value: &T): String;
-
+
-
+## Function `unmarshal`
-## Function `stringify_object`
+Unmarshal JSON bytes to the given struct.
+NOTE: key @type
is converted to _type_
+NOTE: key move
is converted to _move_
-fun stringify_object(value: vector<json::KeyValue>): string::String
+public fun unmarshal<T: drop>(json: vector<u8>): T
-
-Implementation
+##### Implementation
-native fun stringify_object(value: vector<KeyValue>): String;
+native public fun unmarshal<T: drop>(json: vector<u8>): T;
-
-
-
-
diff --git a/initia_stdlib/doc/keccak.md b/initia_stdlib/doc/keccak.md
new file mode 100644
index 0000000..e1b4f62
--- /dev/null
+++ b/initia_stdlib/doc/keccak.md
@@ -0,0 +1,36 @@
+
+
+
+# Module `0x1::keccak`
+
+Cryptographic hashes:
+- Keccak-256: see https://keccak.team/keccak.html
+
+In addition, SHA2-256 and SHA3-256 are available in std::hash
. Note that SHA3-256 is a variant of Keccak: it is
+NOT the same as Keccak-256.
+
+
+- [Function `keccak256`](#0x1_keccak_keccak256)
+
+
+
+
+
+
+
+
+## Function `keccak256`
+
+Returns the Keccak-256 hash of bytes
.
+
+
+public fun keccak256(byte: vector<u8>): vector<u8>
+
+
+
+
+##### Implementation
+
+
+native public fun keccak256(byte: vector<u8>): vector<u8>;
+
diff --git a/initia_stdlib/doc/managed_coin.md b/initia_stdlib/doc/managed_coin.md
index 50748ed..892ff61 100644
--- a/initia_stdlib/doc/managed_coin.md
+++ b/initia_stdlib/doc/managed_coin.md
@@ -10,9 +10,11 @@ By utilizing this current module, a developer can create his own coin and care l
- [Resource `Capabilities`](#0x1_managed_coin_Capabilities)
- [Constants](#@Constants_0)
+- [Function `sudo_mint`](#0x1_managed_coin_sudo_mint)
- [Function `initialize`](#0x1_managed_coin_initialize)
- [Function `burn`](#0x1_managed_coin_burn)
- [Function `mint`](#0x1_managed_coin_mint)
+- [Function `mint_to`](#0x1_managed_coin_mint_to)
use 0x1::coin;
@@ -39,8 +41,7 @@ The resource is stored on the account that initialized coin CoinType
-Fields
+##### Fields
@@ -65,8 +66,6 @@ The resource is stored on the account that initialized coin CoinType
-
-
## Constants
@@ -92,6 +91,49 @@ Metadata has no capabilities (burn/mint).
+
+
+## Function `sudo_mint`
+
+Create new metadata coins and deposit them into dst_addr's account.
+
+
+public entry fun sudo_mint(account: &signer, dst_addr: address, metadata: object::Object<fungible_asset::Metadata>, amount: u64)
+
+
+
+
+##### Implementation
+
+
+public entry fun sudo_mint(
+ account: &signer,
+ dst_addr: address,
+ metadata: Object<Metadata>,
+ amount: u64
+) acquires Capabilities {
+ check_sudo(account);
+
+ let account_addr = signer::address_of(account);
+ assert!(
+ object::is_owner(metadata, account_addr),
+ error::not_found(EUNAUTHORIZED)
+ );
+
+ let object_addr = object::object_address(&metadata);
+ assert!(
+ exists<Capabilities>(object_addr),
+ error::not_found(ENO_CAPABILITIES)
+ );
+
+ let capabilities = borrow_global<Capabilities>(object_addr);
+ let fa = coin::mint(&capabilities.mint_cap, amount);
+ coin::sudo_deposit(dst_addr, fa);
+}
+
+
+
+
## Function `initialize`
@@ -105,8 +147,7 @@ Mint and Burn Capabilities will be stored under metadata
in <
-
-Implementation
+##### Implementation
public entry fun initialize(
@@ -116,31 +157,29 @@ Mint and Burn Capabilities will be stored under metadata
in <
symbol: String,
decimals: u8,
icon_uri: String,
- project_uri: String,
+ project_uri: String
) {
- let (mint_cap, burn_cap, freeze_cap, extend_ref) = coin::initialize_and_generate_extend_ref (
- account,
- maximum_supply,
- name,
- symbol,
- decimals,
- icon_uri,
- project_uri,
- );
+ let (mint_cap, burn_cap, freeze_cap, extend_ref) =
+ coin::initialize_and_generate_extend_ref(
+ account,
+ maximum_supply,
+ name,
+ symbol,
+ decimals,
+ icon_uri,
+ project_uri
+ );
let metadata_signer = object::generate_signer_for_extending(&extend_ref);
- move_to(&metadata_signer, Capabilities {
- mint_cap,
- burn_cap,
- freeze_cap,
- });
+ move_to(
+ &metadata_signer,
+ Capabilities { mint_cap, burn_cap, freeze_cap }
+ );
}
-
-
## Function `burn`
@@ -153,26 +192,23 @@ Withdraw an amount
of metadata coin from burn(
- account: &signer,
- metadata: Object<Metadata>,
- amount: u64,
+ account: &signer, metadata: Object<Metadata>, amount: u64
) acquires Capabilities {
let account_addr = signer::address_of(account);
assert!(
object::is_owner(metadata, account_addr),
- error::not_found(EUNAUTHORIZED),
+ error::not_found(EUNAUTHORIZED)
);
- let object_addr = object::object_address(metadata);
+ let object_addr = object::object_address(&metadata);
assert!(
exists<Capabilities>(object_addr),
- error::not_found(ENO_CAPABILITIES),
+ error::not_found(ENO_CAPABILITIES)
);
let capabilities = borrow_global<Capabilities>(object_addr);
@@ -184,48 +220,67 @@ Withdraw an amount
of metadata coin from
## Function `mint`
-Create new metadata coins and deposit them into dst_addr's account.
+Create new metadata coins.
-public entry fun mint(account: &signer, dst_addr: address, metadata: object::Object<fungible_asset::Metadata>, amount: u64)
+public fun mint(account: &signer, metadata: object::Object<fungible_asset::Metadata>, amount: u64): fungible_asset::FungibleAsset
-
-Implementation
+##### Implementation
-public entry fun mint(
- account: &signer,
- dst_addr: address,
- metadata: Object<Metadata>,
- amount: u64,
-) acquires Capabilities {
+public fun mint(
+ account: &signer, metadata: Object<Metadata>, amount: u64
+): FungibleAsset acquires Capabilities {
let account_addr = signer::address_of(account);
assert!(
object::is_owner(metadata, account_addr),
- error::not_found(EUNAUTHORIZED),
+ error::not_found(EUNAUTHORIZED)
);
- let object_addr = object::object_address(metadata);
+ let object_addr = object::object_address(&metadata);
assert!(
exists<Capabilities>(object_addr),
- error::not_found(ENO_CAPABILITIES),
+ error::not_found(ENO_CAPABILITIES)
);
let capabilities = borrow_global<Capabilities>(object_addr);
- coin::mint_to(&capabilities.mint_cap, dst_addr, amount);
+ coin::mint(&capabilities.mint_cap, amount)
}
-
+
+
+## Function `mint_to`
+
+Create new metadata coins and deposit them into dst_addr's account.
+
+
+public entry fun mint_to(account: &signer, dst_addr: address, metadata: object::Object<fungible_asset::Metadata>, amount: u64)
+
+
+
+
+##### Implementation
+
+
+public entry fun mint_to(
+ account: &signer,
+ dst_addr: address,
+ metadata: Object<Metadata>,
+ amount: u64
+) acquires Capabilities {
+ let fa = mint(account, metadata, amount);
+
+ coin::deposit(dst_addr, fa);
+}
+
diff --git a/initia_stdlib/doc/math128.md b/initia_stdlib/doc/math128.md
index 73bf758..c625ed3 100644
--- a/initia_stdlib/doc/math128.md
+++ b/initia_stdlib/doc/math128.md
@@ -63,8 +63,7 @@ Return the largest of two numbers.
-
-Implementation
+##### Implementation
public fun max(a: u128, b: u128): u128 {
@@ -74,8 +73,6 @@ Return the largest of two numbers.
-
-
## Function `min`
@@ -88,8 +85,7 @@ Return the smallest of two numbers.
-
-Implementation
+##### Implementation
public fun min(a: u128, b: u128): u128 {
@@ -99,8 +95,6 @@ Return the smallest of two numbers.
-
-
## Function `average`
@@ -113,8 +107,7 @@ Return the average of two.
-
-Implementation
+##### Implementation
public fun average(a: u128, b: u128): u128 {
@@ -128,8 +121,6 @@ Return the average of two.
-
-
## Function `mul_div`
@@ -142,8 +133,7 @@ Returns a * b / c going through u128 to prevent intermediate overflow
-
-Implementation
+##### Implementation
public fun mul_div(a: u128, b: u128, c: u128): u128 {
@@ -153,8 +143,6 @@ Returns a * b / c going through u128 to prevent intermediate overflow
-
-
## Function `clamp`
@@ -167,8 +155,7 @@ Return x clamped to the interval [lower, upper].
-
-Implementation
+##### Implementation
public fun clamp(x: u128, lower: u128, upper: u128): u128 {
@@ -178,8 +165,6 @@ Return x clamped to the interval [lower, upper].
-
-
## Function `pow`
@@ -192,14 +177,12 @@ Return the value of n raised to power e
-
-Implementation
+##### Implementation
public fun pow(n: u128, e: u128): u128 {
- if (e == 0) {
- 1
- } else {
+ if (e == 0) { 1 }
+ else {
let p = 1;
while (e > 1) {
if (e % 2 == 1) {
@@ -215,8 +198,6 @@ Return the value of n raised to power e
-
-
## Function `floor_log2`
@@ -229,13 +210,15 @@ Returns floor(log2(x))
-
-Implementation
+##### Implementation
public fun floor_log2(x: u128): u8 {
let res = 0;
- assert!(x != 0, std::error::invalid_argument(EINVALID_ARG_FLOOR_LOG2));
+ assert!(
+ x != 0,
+ std::error::invalid_argument(EINVALID_ARG_FLOOR_LOG2)
+ );
// Effectively the position of the most significant set bit
let n = 64;
while (n > 0) {
@@ -251,8 +234,6 @@ Returns floor(log2(x))
-
-
## Function `log2`
@@ -264,8 +245,7 @@ Returns floor(log2(x))
-
-Implementation
+##### Implementation
public fun log2(x: u128): FixedPoint32 {
@@ -284,17 +264,18 @@ Returns floor(log2(x))
x = (x * x) >> 32;
// x is now in [1, 4)
// if x in [2, 4) then log x = 1 + log (x / 2)
- if (x >= (2 << 32)) { frac = frac + delta; x = x >> 1; };
+ if (x >= (2 << 32)) {
+ frac = frac + delta;
+ x = x >> 1;
+ };
delta = delta >> 1;
};
- fixed_point32::create_from_raw_value (((integer_part as u64) << 32) + frac)
+ fixed_point32::create_from_raw_value(((integer_part as u64) << 32) + frac)
}
-
-
## Function `log2_64`
@@ -306,8 +287,7 @@ Returns floor(log2(x))
-
-Implementation
+##### Implementation
public fun log2_64(x: u128): FixedPoint64 {
@@ -326,17 +306,18 @@ Returns floor(log2(x))
x = (x * x) >> 63;
// x is now in [1, 4)
// if x in [2, 4) then log x = 1 + log (x / 2)
- if (x >= (2 << 63)) { frac = frac + delta; x = x >> 1; };
+ if (x >= (2 << 63)) {
+ frac = frac + delta;
+ x = x >> 1;
+ };
delta = delta >> 1;
};
- fixed_point64::create_from_raw_value (((integer_part as u128) << 64) + frac)
+ fixed_point64::create_from_raw_value(((integer_part as u128) << 64) + frac)
}
-
-
## Function `sqrt`
@@ -349,8 +330,7 @@ Returns square root of x, precisely floor(sqrt(x))
-
-Implementation
+##### Implementation
public fun sqrt(x: u128): u128 {
@@ -375,8 +355,6 @@ Returns square root of x, precisely floor(sqrt(x))
-
-
## Function `ceil_div`
@@ -388,8 +366,7 @@ Returns square root of x, precisely floor(sqrt(x))
-
-Implementation
+##### Implementation
public fun ceil_div(x: u128, y: u128): u128 {
@@ -398,11 +375,6 @@ Returns square root of x, precisely floor(sqrt(x))
if (x == 0) {
assert!(y != 0, EDIVISION_BY_ZERO);
0
- }
- else (x - 1) / y + 1
+ } else (x - 1) / y + 1
}
-
-
-
-
diff --git a/initia_stdlib/doc/math64.md b/initia_stdlib/doc/math64.md
index b9884bb..6d866ba 100644
--- a/initia_stdlib/doc/math64.md
+++ b/initia_stdlib/doc/math64.md
@@ -34,7 +34,7 @@ Standard math utilities missing in the Move Language.
-const EDIVISION_BY_ZERO: u64 = 1;
+const EDIVISION_BY_ZERO: u64 = 2;
@@ -61,8 +61,7 @@ Return the largest of two numbers.
-
-Implementation
+##### Implementation
public fun max(a: u64, b: u64): u64 {
@@ -72,8 +71,6 @@ Return the largest of two numbers.
-
-
## Function `min`
@@ -86,8 +83,7 @@ Return the smallest of two numbers.
-
-Implementation
+##### Implementation
public fun min(a: u64, b: u64): u64 {
@@ -97,8 +93,6 @@ Return the smallest of two numbers.
-
-
## Function `average`
@@ -111,8 +105,7 @@ Return the average of two.
-
-Implementation
+##### Implementation
public fun average(a: u64, b: u64): u64 {
@@ -126,8 +119,6 @@ Return the average of two.
-
-
## Function `mul_div`
@@ -140,8 +131,7 @@ Returns a * b / c going through u128 to prevent intermediate overflow
-
-Implementation
+##### Implementation
public fun mul_div(a: u64, b: u64, c: u64): u64 {
@@ -151,8 +141,6 @@ Returns a * b / c going through u128 to prevent intermediate overflow
-
-
## Function `clamp`
@@ -165,8 +153,7 @@ Return x clamped to the interval [lower, upper].
-
-Implementation
+##### Implementation
public fun clamp(x: u64, lower: u64, upper: u64): u64 {
@@ -176,8 +163,6 @@ Return x clamped to the interval [lower, upper].
-
-
## Function `pow`
@@ -190,14 +175,12 @@ Return the value of n raised to power e
-
-Implementation
+##### Implementation
public fun pow(n: u64, e: u64): u64 {
- if (e == 0) {
- 1
- } else {
+ if (e == 0) { 1 }
+ else {
let p = 1;
while (e > 1) {
if (e % 2 == 1) {
@@ -213,8 +196,6 @@ Return the value of n raised to power e
-
-
## Function `floor_log2`
@@ -227,13 +208,15 @@ Returns floor(lg2(x))
-
-Implementation
+##### Implementation
public fun floor_log2(x: u64): u8 {
let res = 0;
- assert!(x != 0, std::error::invalid_argument(EINVALID_ARG_FLOOR_LOG2));
+ assert!(
+ x != 0,
+ std::error::invalid_argument(EINVALID_ARG_FLOOR_LOG2)
+ );
// Effectively the position of the most significant set bit
let n = 32;
while (n > 0) {
@@ -249,8 +232,6 @@ Returns floor(lg2(x))
-
-
## Function `log2`
@@ -262,18 +243,19 @@ Returns floor(lg2(x))
-
-Implementation
+##### Implementation
public fun log2(x: u64): FixedPoint32 {
let integer_part = floor_log2(x);
// Normalize x to [1, 2) in fixed point 32.
- let y = (if (x >= 1 << 32) {
- x >> (integer_part - 32)
- } else {
- x << (32 - integer_part)
- } as u128);
+ let y = (
+ if (x >= 1 << 32) {
+ x >> (integer_part - 32)
+ } else {
+ x << (32 - integer_part)
+ } as u128
+ );
let frac = 0;
let delta = 1 << 31;
while (delta != 0) {
@@ -282,17 +264,18 @@ Returns floor(lg2(x))
y = (y * y) >> 32;
// x is now in [1, 4)
// if x in [2, 4) then log x = 1 + log (x / 2)
- if (y >= (2 << 32)) { frac = frac + delta; y = y >> 1; };
+ if (y >= (2 << 32)) {
+ frac = frac + delta;
+ y = y >> 1;
+ };
delta = delta >> 1;
};
- fixed_point32::create_from_raw_value (((integer_part as u64) << 32) + frac)
+ fixed_point32::create_from_raw_value(((integer_part as u64) << 32) + frac)
}
-
-
## Function `sqrt`
@@ -305,8 +288,7 @@ Returns square root of x, precisely floor(sqrt(x))
-
-Implementation
+##### Implementation
public fun sqrt(x: u64): u64 {
@@ -330,8 +312,6 @@ Returns square root of x, precisely floor(sqrt(x))
-
-
## Function `ceil_div`
@@ -343,8 +323,7 @@ Returns square root of x, precisely floor(sqrt(x))
-
-Implementation
+##### Implementation
public fun ceil_div(x: u64, y: u64): u64 {
@@ -353,11 +332,6 @@ Returns square root of x, precisely floor(sqrt(x))
if (x == 0) {
assert!(y != 0, EDIVISION_BY_ZERO);
0
- }
- else (x - 1) / y + 1
+ } else (x - 1) / y + 1
}
-
-
-
-
diff --git a/initia_stdlib/doc/minitswap.md b/initia_stdlib/doc/minitswap.md
index e10d74f..3617bc6 100644
--- a/initia_stdlib/doc/minitswap.md
+++ b/initia_stdlib/doc/minitswap.md
@@ -7,65 +7,106 @@
- [Resource `ModuleStore`](#0x1_minitswap_ModuleStore)
- [Resource `VirtualPool`](#0x1_minitswap_VirtualPool)
+- [Struct `Pools`](#0x1_minitswap_Pools)
+- [Struct `UnbondEntity`](#0x1_minitswap_UnbondEntity)
+- [Struct `ArbInfo`](#0x1_minitswap_ArbInfo)
+- [Struct `CreatePoolEvent`](#0x1_minitswap_CreatePoolEvent)
+- [Struct `ChangePoolSizeEvent`](#0x1_minitswap_ChangePoolSizeEvent)
+- [Struct `UpdatePoolParamsEvent`](#0x1_minitswap_UpdatePoolParamsEvent)
- [Struct `ProvideEvent`](#0x1_minitswap_ProvideEvent)
-- [Struct `WithdrawEvent`](#0x1_minitswap_WithdrawEvent)
+- [Struct `UnbondEvent`](#0x1_minitswap_UnbondEvent)
+- [Struct `WithdrawUnbondEvent`](#0x1_minitswap_WithdrawUnbondEvent)
- [Struct `SwapEvent`](#0x1_minitswap_SwapEvent)
-- [Struct `RebalanceEvent`](#0x1_minitswap_RebalanceEvent)
+- [Struct `CreateStableswapPoolEvent`](#0x1_minitswap_CreateStableswapPoolEvent)
+- [Struct `InitiateArbEvent`](#0x1_minitswap_InitiateArbEvent)
+- [Struct `FinalizeArbEvent`](#0x1_minitswap_FinalizeArbEvent)
+- [Struct `RevertArbEvent`](#0x1_minitswap_RevertArbEvent)
+- [Struct `UnbondResponse`](#0x1_minitswap_UnbondResponse)
+- [Struct `ArbResponse`](#0x1_minitswap_ArbResponse)
+- [Struct `ModuleStoreResponse`](#0x1_minitswap_ModuleStoreResponse)
+- [Struct `PoolsResponse`](#0x1_minitswap_PoolsResponse)
+- [Struct `PoolsDetailResponse`](#0x1_minitswap_PoolsDetailResponse)
+- [Struct `VirtualPoolDetail`](#0x1_minitswap_VirtualPoolDetail)
+- [Struct `IBCMemo`](#0x1_minitswap_IBCMemo)
+- [Struct `MemoMove`](#0x1_minitswap_MemoMove)
+- [Struct `MemoAsyncCallback`](#0x1_minitswap_MemoAsyncCallback)
+- [Struct `MemoMoveMessage`](#0x1_minitswap_MemoMoveMessage)
+- [Struct `MemoWasm`](#0x1_minitswap_MemoWasm)
+- [Struct `MemoWasmMessage`](#0x1_minitswap_MemoWasmMessage)
+- [Struct `MemoWasmFunds`](#0x1_minitswap_MemoWasmFunds)
+- [Struct `MemoWasmMinitswapHook`](#0x1_minitswap_MemoWasmMinitswapHook)
+- [Struct `MemoWasmMinitswapHookMsg`](#0x1_minitswap_MemoWasmMinitswapHookMsg)
+- [Struct `FinalizeTokenWithdrawalRequest`](#0x1_minitswap_FinalizeTokenWithdrawalRequest)
+- [Struct `CosmosCoin`](#0x1_minitswap_CosmosCoin)
- [Constants](#@Constants_0)
-- [Function `init_module`](#0x1_minitswap_init_module)
- [Function `get_pool_amount`](#0x1_minitswap_get_pool_amount)
- [Function `get_pool_amount_by_denom`](#0x1_minitswap_get_pool_amount_by_denom)
- [Function `get_peg_keeper_balance`](#0x1_minitswap_get_peg_keeper_balance)
- [Function `get_peg_keeper_balance_by_denom`](#0x1_minitswap_get_peg_keeper_balance_by_denom)
- [Function `swap_simulation`](#0x1_minitswap_swap_simulation)
+- [Function `swap_simulation_given_out`](#0x1_minitswap_swap_simulation_given_out)
- [Function `swap_simulation_by_denom`](#0x1_minitswap_swap_simulation_by_denom)
+- [Function `spot_price`](#0x1_minitswap_spot_price)
+- [Function `get_unbond_list`](#0x1_minitswap_get_unbond_list)
+- [Function `get_arb_info`](#0x1_minitswap_get_arb_info)
+- [Function `get_arb_infos`](#0x1_minitswap_get_arb_infos)
+- [Function `get_module_store`](#0x1_minitswap_get_module_store)
+- [Function `get_pools`](#0x1_minitswap_get_pools)
+- [Function `get_pools_list`](#0x1_minitswap_get_pools_list)
+- [Function `get_pools_detail`](#0x1_minitswap_get_pools_detail)
+- [Function `get_pools_detail_list`](#0x1_minitswap_get_pools_detail_list)
+- [Function `unpack_unbond_response`](#0x1_minitswap_unpack_unbond_response)
+- [Function `unpack_arb_response`](#0x1_minitswap_unpack_arb_response)
+- [Function `unpack_module_store_response`](#0x1_minitswap_unpack_module_store_response)
+- [Function `unpack_pools_response`](#0x1_minitswap_unpack_pools_response)
+- [Function `unpack_pools_detail_response`](#0x1_minitswap_unpack_pools_detail_response)
+- [Function `unpack_virtual_pool_detail`](#0x1_minitswap_unpack_virtual_pool_detail)
- [Function `create_pool`](#0x1_minitswap_create_pool)
+- [Function `set_emergency_state`](#0x1_minitswap_set_emergency_state)
- [Function `deactivate`](#0x1_minitswap_deactivate)
- [Function `activate`](#0x1_minitswap_activate)
- [Function `change_pool_size`](#0x1_minitswap_change_pool_size)
- [Function `update_module_params`](#0x1_minitswap_update_module_params)
- [Function `update_pool_params`](#0x1_minitswap_update_pool_params)
- [Function `provide`](#0x1_minitswap_provide)
-- [Function `withdraw`](#0x1_minitswap_withdraw)
+- [Function `unbond`](#0x1_minitswap_unbond)
+- [Function `withdraw_unbond`](#0x1_minitswap_withdraw_unbond)
- [Function `swap`](#0x1_minitswap_swap)
-- [Function `rebalance`](#0x1_minitswap_rebalance)
+- [Function `finalize_arb`](#0x1_minitswap_finalize_arb)
+- [Function `finalize_arb_hook`](#0x1_minitswap_finalize_arb_hook)
+- [Function `create_stableswap_pool`](#0x1_minitswap_create_stableswap_pool)
- [Function `provide_internal`](#0x1_minitswap_provide_internal)
-- [Function `withdraw_internal`](#0x1_minitswap_withdraw_internal)
+- [Function `unbond_internal`](#0x1_minitswap_unbond_internal)
- [Function `swap_internal`](#0x1_minitswap_swap_internal)
-- [Function `rebalance_internal`](#0x1_minitswap_rebalance_internal)
-- [Function `borrow_all_mut`](#0x1_minitswap_borrow_all_mut)
-- [Function `borrow_all`](#0x1_minitswap_borrow_all)
-- [Function `calc_peg_keeper_swap`](#0x1_minitswap_calc_peg_keeper_swap)
-- [Function `l1_init_metadata`](#0x1_minitswap_l1_init_metadata)
-- [Function `share_token_metadata`](#0x1_minitswap_share_token_metadata)
-- [Function `total_share`](#0x1_minitswap_total_share)
-- [Function `assert_is_chain`](#0x1_minitswap_assert_is_chain)
-- [Function `mul_div`](#0x1_minitswap_mul_div)
-- [Function `is_l1_init`](#0x1_minitswap_is_l1_init)
-- [Function `is_l1_init_metadata`](#0x1_minitswap_is_l1_init_metadata)
-- [Function `get_d0`](#0x1_minitswap_get_d0)
-- [Function `get_d`](#0x1_minitswap_get_d)
-- [Function `get_return_amount`](#0x1_minitswap_get_return_amount)
-- [Function `get_y`](#0x1_minitswap_get_y)
-- [Function `get_fully_recovered_ratio`](#0x1_minitswap_get_fully_recovered_ratio)
-- [Function `get_fully_recovered_pool_amounts`](#0x1_minitswap_get_fully_recovered_pool_amounts)
-- [Function `decimal128_safe_mul`](#0x1_minitswap_decimal128_safe_mul)
-- [Function `decimal128_safe_from_ratio`](#0x1_minitswap_decimal128_safe_from_ratio)
-- [Function `assert_min_amount`](#0x1_minitswap_assert_min_amount)
-
-
-use 0x1::block;
+- [Function `ibc_ack`](#0x1_minitswap_ibc_ack)
+- [Function `ibc_timeout`](#0x1_minitswap_ibc_timeout)
+- [Function `safe_swap_simulation`](#0x1_minitswap_safe_swap_simulation)
+- [Function `safe_swap_simulation_given_out`](#0x1_minitswap_safe_swap_simulation_given_out)
+
+
+use 0x1::address;
+use 0x1::base64;
+use 0x1::bcs;
+use 0x1::bigdecimal;
+use 0x1::block;
use 0x1::coin;
-use 0x1::decimal128;
+use 0x1::cosmos;
use 0x1::error;
use 0x1::event;
use 0x1::fungible_asset;
+use 0x1::hash;
+use 0x1::hex;
+use 0x1::json;
use 0x1::object;
use 0x1::option;
use 0x1::primary_fungible_store;
use 0x1::signer;
+use 0x1::stableswap;
use 0x1::string;
+use 0x1::string_utils;
use 0x1::table;
+use 0x1::table_key;
+use 0x1::vector;
@@ -81,8 +122,7 @@
-
-Fields
+##### Fields
@@ -93,28 +133,46 @@
Extend reference
-
-
pools: table::Table<object::Object<fungible_asset::Metadata>, object::Object<minitswap::VirtualPool>>
+pools: table::Table<object::Object<fungible_asset::Metadata>, minitswap::Pools>
-
List of pools
-
-
l1_init_amount: u64
+max_change_rate: bigdecimal::BigDecimal
+
+-
+ Max pool size change rate
+
+-
+
emergency_state: bool
+
+-
+ If this state is True, every depositor related transaction sent to Minitswap will fail
+
+-
+
admin: address
+
+-
+ admin address who can change emergency_state and pool active
+
+-
+
depositor_owned_init: u64
-
Not real balance, the amount for shares
-
-
swap_fee_rate: decimal128::Decimal128
+unbond_period: u64
-
- Swap fee rate
+ unbond period
-
-
max_change_rate: decimal128::Decimal128
+unbond_wait_list: table::Table<vector<u8>, minitswap::UnbondEntity>
-
- Max pool size change rate
+ unbond wait list. key: address + release time
-
mint_cap: coin::MintCapability
@@ -128,11 +186,75 @@
-
burn capability of liquidity token
+-
+
stableswap_ann: u64
+
+-
+ ANN
+
+-
+
stableswap_swap_fee_rate: bigdecimal::BigDecimal
+
+-
+ swap fee rate
+
+-
+
swap_fee_rate: bigdecimal::BigDecimal
+
+-
+ Swap fee rate
+
+-
+
arb_fee_rate: bigdecimal::BigDecimal
+
+-
+ Swap fee rate
+
+-
+
trigger_fee: u64
+
+-
+ The amount of uinit that the user will take during finalization of in-house arb
+
+-
+
min_arb_profit: u64
+
+-
+ The minimum time needed to trigger the arbitrage
+
+-
+
ibc_timeout: u64
+
+-
+ How much minimum pegkeeper ibc_op_init balance is needed to trigger the arb
+
+-
+
max_arb_batch: u64
+
+-
+ Maximum arb_batch size
+
+-
+
min_arb_interval: u64
+
+-
+ Minimum arb interval
+
+-
+
global_arb_batch_map: table::Table<vector<u8>, object::Object<minitswap::VirtualPool>>
+
+-
+ global arb map. index => Virtual Pool
+
+-
+
arb_batch_index: u64
+
+-
+ arb batc index
+
-
-
## Resource `VirtualPool`
@@ -144,12 +266,17 @@
-
-Fields
+##### Fields
-
+
ibc_op_init_metadata: object::Object<fungible_asset::Metadata>
+
+-
+ IBC OP init metadata
+
+-
extend_ref: object::ExtendRef
-
@@ -162,34 +289,34 @@
Z. Virtual pool size
-
-
recover_velocity: decimal128::Decimal128
+recover_velocity: bigdecimal::BigDecimal
-
V. Recover velocity. Real recover amount = Vt
-
-
max_ratio: decimal128::Decimal128
+max_ratio: bigdecimal::BigDecimal
-
R_max max recover ratio
-
-
recover_param: decimal128::Decimal128
+recover_param: bigdecimal::BigDecimal
-
f. Flexibility
-
-
l1_pool_amount: u64
+init_pool_amount: u64
-
- Virtual pool amount of L1 INIT
+ Virtual pool amount of INIT
-
-
l2_pool_amount: u64
+ibc_op_init_pool_amount: u64
-
- Virtual pool amount of L2 INIT
+ Virtual pool amount of ibc_op_INIT
-
last_recovered_timestamp: u64
@@ -198,16 +325,22 @@
last recovered timestamp
-
-
virtual_l1_balance: u64
+virtual_init_balance: u64
+
+ -
+ INIT balance of peg keeper (negative value)
+
+-
+
virtual_ibc_op_init_balance: u64
-
- L1 INIT balance of peg keeper (negative value)
+ ibc op INIT balance of peg keeper
-
-
virtual_l2_balance: u64
+peg_keeper_owned_ibc_op_init_balance: u64
-
- L2 INIT balance of peg keeper
+ ibc op INIT balance of peg keeper which also include unprocessed arb_batch state.
-
ann: u64
@@ -221,72 +354,74 @@
-
Is pool in active
+-
+
op_bridge_id: u64
+
+-
+ op bridge id
+
+-
+
ibc_channel: string::String
+
+-
+ ibc channel
+
+-
+
vm_type: u8
+
+-
+ layer 2 vm type. One of MOVE or COSMWASM
+
+-
+
hook_contract: string::String
+
+-
+ hook contract
+
+-
+
arb_batch_map: table::Table<vector<u8>, minitswap::ArbInfo>
+
+-
+ ongoing in house arb info
+
-
-
-
+
-## Struct `ProvideEvent`
+## Struct `Pools`
-Event emitted when provide.
-#[event]
-struct ProvideEvent has drop, store
+struct Pools has store
-
-Fields
+##### Fields
-
-
provide_amount: u64
+op_bridge_id: u64
-
-
-
share_amount: u64
+ibc_channel: string::String
-
-
-
-
-
-
-
-
-## Struct `WithdrawEvent`
-
-Event emitted when withdraw.
-
-
-#[event]
-struct WithdrawEvent has drop, store
-
-
-
-
-
-Fields
-
-
-
-
-
withdraw_amount: u64
+virtual_pool: option::Option<object::Object<minitswap::VirtualPool>>
-
-
-
share_amount: u64
+stableswap_pool: option::Option<object::Object<stableswap::Pool>>
-
@@ -294,64 +429,83 @@ Event emitted when withdraw.
-
-
-
+
-## Struct `SwapEvent`
+## Struct `UnbondEntity`
-Event emitted when swap token.
-#[event]
-struct SwapEvent has drop, store
+struct UnbondEntity has store
-
-Fields
+##### Fields
-
-
offer_coin: object::Object<fungible_asset::Metadata>
+account: address
-
-
-
return_coin: object::Object<fungible_asset::Metadata>
+share_amount: u64
-
-
-
peg_keeper_offer_amount: u64
+withdraw_amount: u64
-
-
-
peg_keeper_return_amount: u64
+release_time: u64
+
+-
+
+
+
+
+
+
+
+## Struct `ArbInfo`
+
+
+
+struct ArbInfo has store
+
+
+
+
+##### Fields
+
+
+
+-
+
executed_time: u64
-
-
-
offer_amount: u64
+init_used: u64
-
-
-
return_amount: u64
+ibc_op_init_sent: u64
-
-
-
fee_amount: u64
+triggering_fee: u64
-
@@ -359,152 +513,1472 @@ Event emitted when swap token.
-
+
-
+## Struct `CreatePoolEvent`
-## Struct `RebalanceEvent`
-
-Event emitted when rebalance peg keeper's balances.
+Event emitted when virtual pool created
#[event]
-struct RebalanceEvent has drop, store
+struct CreatePoolEvent has drop, store
-
-Fields
+##### Fields
-
-
offer_coin: object::Object<fungible_asset::Metadata>
+ibc_op_init_metadata: object::Object<fungible_asset::Metadata>
-
-
-
return_coin: object::Object<fungible_asset::Metadata>
+recover_velocity: bigdecimal::BigDecimal
-
-
-
offer_amount: u64
+pool_size: u64
-
-
-
return_amount: u64
+ann: u64
-
-
-
fee_amount: u64
+max_ratio: bigdecimal::BigDecimal
-
-
-
-
-
+-
+
recover_param: bigdecimal::BigDecimal
+
+-
-
+
+
-## Constants
+
-
+## Struct `ChangePoolSizeEvent`
+Event emitted when virtual pool size changed
-const EMIN_RETURN: u64 = 9;
+#[event]
+struct ChangePoolSizeEvent has drop, store
-
-
-
-
-const A_PRECISION: u256 = 100;
-
+##### Fields
+
+-
+
ibc_op_init_metadata: object::Object<fungible_asset::Metadata>
+
+-
-
-
+
+-
+
pool_size: u64
+
+-
+
+-
+
depositor_owned_init_increase: u64
+
+-
-
const EINACTIVE: u64 = 5;
-
+
+
+
-
+## Struct `UpdatePoolParamsEvent`
+Event emitted when update param of virtual pool
-const EL2_PRICE_TOO_LOW: u64 = 7;
+#[event]
+struct UpdatePoolParamsEvent has drop, store
-
-
+##### Fields
-const EMAX_CHANGE: u64 = 8;
-
+
+-
+
ibc_op_init_metadata: object::Object<fungible_asset::Metadata>
+
+-
+
+-
+
recover_velocity: option::Option<bigdecimal::BigDecimal>
+
+-
+
+-
+
ann: option::Option<u64>
+
+-
-
+
+-
+
max_ratio: option::Option<bigdecimal::BigDecimal>
+
+-
+
+-
+
recover_param: option::Option<bigdecimal::BigDecimal>
+
+-
+
+-
+
hook_contract: option::Option<string::String>
+
+-
-
const ENOT_CHAIN: u64 = 1;
-
+
+
+
-
+## Struct `ProvideEvent`
+Event emitted when provide.
-const ENOT_ENOUGH_BALANCE: u64 = 4;
+#[event]
+struct ProvideEvent has drop, store
-
+##### Fields
+
+-
+
provide_amount: u64
+
+-
+
+
+-
+
share_amount: u64
+
+-
-
const ENOT_L1_INIT: u64 = 3;
-
+
+
+
-
+## Struct `UnbondEvent`
+Event emitted when unbond.
-const ENOT_SHARE_TOKEN: u64 = 6;
+#[event]
+struct UnbondEvent has drop, store
-
-
+##### Fields
-const EPOOL_NOT_FOUND: u64 = 2;
+
+-
+
account: address
+
+-
+
+
+-
+
share_amount: u64
+
+-
+
+
+-
+
withdraw_amount: u64
+
+-
+
+
+-
+
release_time: u64
+
+-
+
+
+
+
+
+
+
+## Struct `WithdrawUnbondEvent`
+
+Event emitted when withdraw unbond.
+
+
+#[event]
+struct WithdrawUnbondEvent has drop, store
+
+
+
+
+##### Fields
+
+
+
+-
+
account: address
+
+-
+
+
+-
+
share_amount: u64
+
+-
+
+
+-
+
withdraw_amount: u64
+
+-
+
+
+-
+
release_time: u64
+
+-
+
+
+
+
+
+
+
+## Struct `SwapEvent`
+
+Event emitted when swap token.
+
+
+#[event]
+struct SwapEvent has drop, store
+
+
+
+
+##### Fields
+
+
+
+-
+
offer_coin: object::Object<fungible_asset::Metadata>
+
+-
+
+
+-
+
return_coin: object::Object<fungible_asset::Metadata>
+
+-
+
+
+-
+
peg_keeper_offer_amount: u64
+
+-
+
+
+-
+
peg_keeper_return_amount: u64
+
+-
+
+
+-
+
offer_amount: u64
+
+-
+
+
+-
+
return_amount: u64
+
+-
+
+
+-
+
init_swap_fee_amount: u64
+
+-
+
+
+-
+
init_arb_fee_amount: u64
+
+-
+
+
+-
+
ibc_op_init_swap_fee_amount: u64
+
+-
+
+
+-
+
ibc_op_init_arb_fee_amount: u64
+
+-
+
+
+
+
+
+
+
+## Struct `CreateStableswapPoolEvent`
+
+Event emitted when stable swap pool created
+
+
+#[event]
+struct CreateStableswapPoolEvent has drop, store
+
+
+
+
+##### Fields
+
+
+
+-
+
ibc_op_init_metadata: object::Object<fungible_asset::Metadata>
+
+-
+
+
+-
+
pool: object::Object<stableswap::Pool>
+
+-
+
+
+
+
+
+
+
+## Struct `InitiateArbEvent`
+
+Event emitted when arb initiated
+
+
+#[event]
+struct InitiateArbEvent has drop, store
+
+
+
+
+##### Fields
+
+
+
+-
+
arb_index: u64
+
+-
+
+
+-
+
pool: object::Object<minitswap::VirtualPool>
+
+-
+
+
+-
+
executed_time: u64
+
+-
+
+
+-
+
init_used: u64
+
+-
+
+
+-
+
ibc_op_init_sent: u64
+
+-
+
+
+-
+
triggering_fee: u64
+
+-
+
+
+
+
+
+
+
+## Struct `FinalizeArbEvent`
+
+Event emitted when arb finalized
+
+
+#[event]
+struct FinalizeArbEvent has drop, store
+
+
+
+
+##### Fields
+
+
+
+-
+
arb_index: u64
+
+-
+
+
+-
+
pool: object::Object<minitswap::VirtualPool>
+
+-
+
+
+-
+
init_used: u64
+
+-
+
+
+-
+
ibc_op_init_sent: u64
+
+-
+
+
+-
+
triggering_fee: u64
+
+-
+
+
+
+
+
+
+
+## Struct `RevertArbEvent`
+
+Event emitted when arb reverted
+
+
+#[event]
+struct RevertArbEvent has drop, store
+
+
+
+
+##### Fields
+
+
+
+-
+
arb_index: u64
+
+-
+
+
+-
+
pool: object::Object<minitswap::VirtualPool>
+
+-
+
+
+-
+
init_used: u64
+
+-
+
+
+-
+
ibc_op_init_sent: u64
+
+-
+
+
+-
+
triggering_fee: u64
+
+-
+
+
+
+
+
+
+
+## Struct `UnbondResponse`
+
+
+
+struct UnbondResponse has drop
+
+
+
+
+##### Fields
+
+
+
+-
+
account: address
+
+-
+
+
+-
+
share_amount: u64
+
+-
+
+
+-
+
withdraw_amount: u64
+
+-
+
+
+-
+
release_time: u64
+
+-
+
+
+
+
+
+
+
+## Struct `ArbResponse`
+
+
+
+struct ArbResponse has drop
+
+
+
+
+##### Fields
+
+
+
+-
+
ibc_op_init_metadata: object::Object<fungible_asset::Metadata>
+
+-
+
+
+-
+
id: u64
+
+-
+
+
+-
+
executed_time: u64
+
+-
+
+
+-
+
init_used: u64
+
+-
+
+
+-
+
ibc_op_init_sent: u64
+
+-
+
+
+-
+
triggering_fee: u64
+
+-
+
+
+
+
+
+
+
+## Struct `ModuleStoreResponse`
+
+
+
+struct ModuleStoreResponse has drop
+
+
+
+
+##### Fields
+
+
+
+-
+
max_change_rate: bigdecimal::BigDecimal
+
+-
+
+
+-
+
emergency_state: bool
+
+-
+
+
+-
+
admin: address
+
+-
+
+
+-
+
depositor_owned_init: u64
+
+-
+
+
+-
+
unbond_period: u64
+
+-
+
+
+-
+
swap_fee_rate: bigdecimal::BigDecimal
+
+-
+
+
+-
+
arb_fee_rate: bigdecimal::BigDecimal
+
+-
+
+
+-
+
trigger_fee: u64
+
+-
+
+
+-
+
min_arb_profit: u64
+
+-
+
+
+-
+
ibc_timeout: u64
+
+-
+
+
+-
+
max_arb_batch: u64
+
+-
+
+
+-
+
min_arb_interval: u64
+
+-
+
+
+-
+
arb_batch_index: u64
+
+-
+
+
+
+
+
+
+
+## Struct `PoolsResponse`
+
+
+
+struct PoolsResponse has drop
+
+
+
+
+##### Fields
+
+
+
+-
+
ibc_op_init_metadata: object::Object<fungible_asset::Metadata>
+
+-
+
+
+-
+
ibc_op_init_denom: string::String
+
+-
+
+
+-
+
op_bridge_id: u64
+
+-
+
+
+-
+
ibc_channel: string::String
+
+-
+
+
+-
+
virtual_pool: option::Option<object::Object<minitswap::VirtualPool>>
+
+-
+
+
+-
+
stableswap_pool: option::Option<object::Object<stableswap::Pool>>
+
+-
+
+
+
+
+
+
+
+## Struct `PoolsDetailResponse`
+
+
+
+struct PoolsDetailResponse has drop
+
+
+
+
+##### Fields
+
+
+
+-
+
ibc_op_init_metadata: object::Object<fungible_asset::Metadata>
+
+-
+
+
+-
+
ibc_op_init_denom: string::String
+
+-
+
+
+-
+
op_bridge_id: u64
+
+-
+
+
+-
+
ibc_channel: string::String
+
+-
+
+
+-
+
virtual_pool: option::Option<minitswap::VirtualPoolDetail>
+
+-
+
+
+-
+
stableswap_pool: option::Option<stableswap::PoolResponse>
+
+-
+
+
+
+
+
+
+
+## Struct `VirtualPoolDetail`
+
+
+
+struct VirtualPoolDetail has drop
+
+
+
+
+##### Fields
+
+
+
+-
+
pool_size: u64
+
+-
+
+
+-
+
recover_velocity: bigdecimal::BigDecimal
+
+-
+
+
+-
+
max_ratio: bigdecimal::BigDecimal
+
+-
+
+
+-
+
recover_param: bigdecimal::BigDecimal
+
+-
+
+
+-
+
init_pool_amount: u64
+
+-
+
+
+-
+
ibc_op_init_pool_amount: u64
+
+-
+
+
+-
+
last_recovered_timestamp: u64
+
+-
+
+
+-
+
virtual_init_balance: u64
+
+-
+
+
+-
+
virtual_ibc_op_init_balance: u64
+
+-
+
+
+-
+
peg_keeper_owned_ibc_op_init_balance: u64
+
+-
+
+
+-
+
ann: u64
+
+-
+
+
+-
+
active: bool
+
+-
+
+
+
+
+
+
+
+## Struct `IBCMemo`
+
+
+
+struct IBCMemo has copy, drop
+
+
+
+
+##### Fields
+
+
+
+-
+
_move_: minitswap::MemoMove
+
+-
+
+
+-
+
wasm: option::Option<minitswap::MemoWasm>
+
+-
+
+
+
+
+
+
+
+## Struct `MemoMove`
+
+
+
+struct MemoMove has copy, drop
+
+
+
+
+##### Fields
+
+
+
+-
+
message: option::Option<minitswap::MemoMoveMessage>
+
+-
+
+
+-
+
async_callback: minitswap::MemoAsyncCallback
+
+-
+
+
+
+
+
+
+
+## Struct `MemoAsyncCallback`
+
+
+
+struct MemoAsyncCallback has copy, drop
+
+
+
+
+##### Fields
+
+
+
+-
+
id: u64
+
+-
+
+
+-
+
module_address: address
+
+-
+
+
+-
+
module_name: string::String
+
+-
+
+
+
+
+
+
+
+## Struct `MemoMoveMessage`
+
+
+
+struct MemoMoveMessage has copy, drop
+
+
+
+
+##### Fields
+
+
+
+-
+
module_address: string::String
+
+-
+
+
+-
+
module_name: string::String
+
+-
+
+
+-
+
function_name: string::String
+
+-
+
+
+-
+
type_args: vector<string::String>
+
+-
+
+
+-
+
args: vector<string::String>
+
+-
+
+
+
+
+
+
+
+## Struct `MemoWasm`
+
+
+
+struct MemoWasm has copy, drop
+
+
+
+
+##### Fields
+
+
+
+-
+
message: minitswap::MemoWasmMessage
+
+-
+
+
+
+
+
+
+
+## Struct `MemoWasmMessage`
+
+
+
+struct MemoWasmMessage has copy, drop
+
+
+
+
+##### Fields
+
+
+
+-
+
contracts: string::String
+
+-
+
+
+-
+
funds: vector<minitswap::MemoWasmFunds>
+
+-
+
+
+-
+
msg: minitswap::MemoWasmMinitswapHook
+
+-
+
+
+
+
+
+
+
+## Struct `MemoWasmFunds`
+
+
+
+struct MemoWasmFunds has copy, drop
+
+
+
+
+##### Fields
+
+
+
+-
+
denom: string::String
+
+-
+
+
+-
+
amount: string::String
+
+-
+
+
+
+
+
+
+
+## Struct `MemoWasmMinitswapHook`
+
+
+
+struct MemoWasmMinitswapHook has copy, drop
+
+
+
+
+##### Fields
+
+
+
+-
+
minitswap_hook: minitswap::MemoWasmMinitswapHookMsg
+
+-
+
+
+
+
+
+
+
+## Struct `MemoWasmMinitswapHookMsg`
+
+
+
+struct MemoWasmMinitswapHookMsg has copy, drop
+
+
+
+
+##### Fields
+
+
+
+-
+
receiver: string::String
+
+-
+
+
+
+
+
+
+
+## Struct `FinalizeTokenWithdrawalRequest`
+
+
+
+struct FinalizeTokenWithdrawalRequest has copy, drop
+
+
+
+
+##### Fields
+
+
+
+-
+
_type_: string::String
+
+-
+
+
+-
+
bridge_id: u64
+
+-
+
+
+-
+
output_index: u64
+
+-
+
+
+-
+
withdrawal_proofs: vector<string::String>
+
+-
+
+
+-
+
sender: string::String
+
+-
+
+
+-
+
receiver: string::String
+
+-
+
+
+-
+
sequence: u64
+
+-
+
+
+-
+
amount: minitswap::CosmosCoin
+
+-
+
+
+-
+
version: string::String
+
+-
+
+
+-
+
state_root: string::String
+
+-
+
+
+-
+
storage_root: string::String
+
+-
+
+
+-
+
latest_block_hash: string::String
+
+-
+
+
+
+
+
+
+
+## Struct `CosmosCoin`
+
+
+
+struct CosmosCoin has copy, drop
+
+
+
+
+##### Fields
+
+
+
+-
+
denom: string::String
+
+-
+
+
+-
+
amount: u64
+
+-
+
+
+
+
+
+
+
+## Constants
+
+
+
+
+
+
+const EAMOUNT_MISMATCH: u64 = 13;
+
+
+
+
+
+
+
+
+const EUNAUTHORIZED: u64 = 1;
+
+
+
+
+
+
+
+
+const EMIN_RETURN: u64 = 9;
+
+
+
+
+
+
+
+
+const MAX_LIMIT: u64 = 30;
+
+
+
+
+
+
+
+
+const A_PRECISION: u256 = 100;
+
+
+
+
+
+
+
+
+const COSMWASM: u8 = 1;
+
+
+
+
+
+
+
+
+const EEMERGENCY: u64 = 14;
+
+
+
+
+
+
+
+
+const EIBC_OP_INIT_PRICE_TOO_LOW: u64 = 7;
+
+
+
+
+
+
+
+
+const EINACTIVE: u64 = 5;
+
+
+
+
+
+
+
+
+const EINVAILD_METADATA: u64 = 16;
+
+
+
+
+
+
+
+
+const EMAX_CHANGE: u64 = 8;
+
+
+
+
+
+
+
+
+const ENOT_ENOUGH_BALANCE: u64 = 4;
+
+
+
+
+
+
+
+
+const ENOT_INIT: u64 = 3;
+
+
+
+
+
+
+
+
+const ENOT_SHARE_TOKEN: u64 = 6;
+
+
+
+
+
+
+
+
+const EPOOL_NOT_FOUND: u64 = 2;
@@ -518,68 +1992,68 @@ Event emitted when rebalance peg keeper's balances.
-
+
-const SYMBOL: vector<u8> = [109, 105, 110, 105, 116, 115, 119, 97, 112, 95, 108, 112];
+const ERELEASE_TIME: u64 = 15;
-
+
-const U64_MAX: u128 = 18446744073709551615;
+const ESMALL_ARB_PROFIT: u64 = 17;
-
+
+
+
+
+const EVIRTUAL_POOL_EXISTS: u64 = 18;
+
+
+
-## Function `init_module`
+
-fun init_module(chain: &signer)
+const EVM_TYPE: u64 = 12;
-
-Implementation
+
-fun init_module(chain: &signer) {
- let constructor_ref = object::create_object(@initia_std, false);
- let extend_ref = object::generate_extend_ref(&constructor_ref);
- let (mint_cap, burn_cap, _) = coin::initialize(
- chain,
- option::some(U64_MAX),
- string::utf8(b"minitswap liquidity token"),
- string::utf8(SYMBOL),
- 6,
- string::utf8(b""),
- string::utf8(b""),
- );
+const MOVE: u8 = 0;
+
- move_to(chain, ModuleStore {
- extend_ref,
- pools: table::new(),
- l1_init_amount: 0,
- swap_fee_rate: decimal128::from_ratio(1, 1000), // 0.1%
- max_change_rate: decimal128::from_ratio(1, 10), // 10%
- mint_cap,
- burn_cap,
- });
-}
+
+
+
+
+
+
+const SYMBOL: vector<u8> = [117, 111, 105, 110, 105, 116];
-
+
+
+
+
+const U64_MAX: u128 = 18446744073709551615;
+
+
+
@@ -588,34 +2062,44 @@ Event emitted when rebalance peg keeper's balances.
#[view]
-public fun get_pool_amount(l2_init_metadata: object::Object<fungible_asset::Metadata>, after_peg_keeper_swap: bool): (u64, u64)
+public fun get_pool_amount(ibc_op_init_metadata: object::Object<fungible_asset::Metadata>, after_peg_keeper_swap: bool): (u64, u64)
-
-Implementation
+##### Implementation
public fun get_pool_amount(
- l2_init_metadata: Object<Metadata>,
- after_peg_keeper_swap: bool,
+ ibc_op_init_metadata: Object<Metadata>, after_peg_keeper_swap: bool
): (u64, u64) acquires ModuleStore, VirtualPool {
- let (_, pool) = borrow_all(l2_init_metadata);
+ let virtual_pool_exists = virtual_pool_exists(ibc_op_init_metadata);
+
+ assert!(
+ virtual_pool_exists,
+ error::invalid_argument(EPOOL_NOT_FOUND)
+ );
+
+ let module_store = borrow_global_mut<ModuleStore>(@initia_std);
+ let pools = table::borrow(&mut module_store.pools, ibc_op_init_metadata);
+ let pool =
+ borrow_global_mut<VirtualPool>(
+ object::object_address(&*option::borrow(&pools.virtual_pool))
+ );
assert!(pool.active, error::invalid_state(EINACTIVE));
- let (swap_amount, return_amount) = if (after_peg_keeper_swap) {
- calc_peg_keeper_swap(pool)
- } else {
- (0, 0)
- };
- return (pool.l1_pool_amount + swap_amount, pool.l2_pool_amount - return_amount)
+ let (swap_amount, return_amount) =
+ if (after_peg_keeper_swap) {
+ calc_peg_keeper_swap(pool)
+ } else { (0, 0) };
+ return (
+ pool.init_pool_amount + swap_amount,
+ pool.ibc_op_init_pool_amount - return_amount
+ )
}
-
-
## Function `get_pool_amount_by_denom`
@@ -623,28 +2107,24 @@ Event emitted when rebalance peg keeper's balances.
#[view]
-public fun get_pool_amount_by_denom(l2_init_denom: string::String, after_peg_keeper_swap: bool): (u64, u64)
+public fun get_pool_amount_by_denom(ibc_op_init_denom: string::String, after_peg_keeper_swap: bool): (u64, u64)
-
-Implementation
+##### Implementation
public fun get_pool_amount_by_denom(
- l2_init_denom: String,
- after_peg_keeper_swap: bool,
+ ibc_op_init_denom: String, after_peg_keeper_swap: bool
): (u64, u64) acquires ModuleStore, VirtualPool {
- let l2_init_metadata = coin::denom_to_metadata(l2_init_denom);
- get_pool_amount(l2_init_metadata, after_peg_keeper_swap)
+ let ibc_op_init_metadata = coin::denom_to_metadata(ibc_op_init_denom);
+ get_pool_amount(ibc_op_init_metadata, after_peg_keeper_swap)
}
-
-
## Function `get_peg_keeper_balance`
@@ -652,35 +2132,33 @@ Event emitted when rebalance peg keeper's balances.
#[view]
-public fun get_peg_keeper_balance(l2_init_metadata: object::Object<fungible_asset::Metadata>, after_peg_keeper_swap: bool): (u64, u64)
+public fun get_peg_keeper_balance(ibc_op_init_metadata: object::Object<fungible_asset::Metadata>, after_peg_keeper_swap: bool): (u64, u64)
-
-Implementation
+##### Implementation
public fun get_peg_keeper_balance(
- l2_init_metadata: Object<Metadata>,
- after_peg_keeper_swap: bool,
+ ibc_op_init_metadata: Object<Metadata>, after_peg_keeper_swap: bool
): (u64, u64) acquires ModuleStore, VirtualPool {
- let (_, pool) = borrow_all(l2_init_metadata);
+ let (_, pool) = borrow_all(ibc_op_init_metadata);
assert!(pool.active, error::invalid_state(EINACTIVE));
- let (swap_amount, return_amount) = if (after_peg_keeper_swap) {
- calc_peg_keeper_swap(pool)
- } else {
- (0, 0)
- };
-
- return (pool.virtual_l1_balance + swap_amount, pool.virtual_l2_balance + return_amount)
+ let (swap_amount, return_amount) =
+ if (after_peg_keeper_swap) {
+ calc_peg_keeper_swap(pool)
+ } else { (0, 0) };
+
+ return (
+ pool.virtual_init_balance + swap_amount,
+ pool.virtual_ibc_op_init_balance + return_amount
+ )
}
-
-
## Function `get_peg_keeper_balance_by_denom`
@@ -688,28 +2166,24 @@ Event emitted when rebalance peg keeper's balances.
#[view]
-public fun get_peg_keeper_balance_by_denom(l2_init_denom: string::String, after_peg_keeper_swap: bool): (u64, u64)
+public fun get_peg_keeper_balance_by_denom(ibc_op_init_denom: string::String, after_peg_keeper_swap: bool): (u64, u64)
-
-Implementation
+##### Implementation
public fun get_peg_keeper_balance_by_denom(
- l2_init_denom: String,
- after_peg_keeper_swap: bool,
+ ibc_op_init_denom: String, after_peg_keeper_swap: bool
): (u64, u64) acquires ModuleStore, VirtualPool {
- let l2_init_metadata = coin::denom_to_metadata(l2_init_denom);
- get_peg_keeper_balance(l2_init_metadata, after_peg_keeper_swap)
+ let ibc_op_init_metadata = coin::denom_to_metadata(ibc_op_init_denom);
+ get_peg_keeper_balance(ibc_op_init_metadata, after_peg_keeper_swap)
}
-
-
## Function `swap_simulation`
@@ -722,53 +2196,65 @@ Event emitted when rebalance peg keeper's balances.
-
-Implementation
+##### Implementation
public fun swap_simulation(
offer_metadata: Object<Metadata>,
return_metadata: Object<Metadata>,
- offer_amount: u64,
+ offer_amount: u64
): (u64, u64) acquires ModuleStore, VirtualPool {
- let is_l1_init_offered = is_l1_init_metadata(offer_metadata);
- let l2_init_metadata = if(is_l1_init_offered) {
- return_metadata
- } else {
- offer_metadata
- };
-
- let (_, pool) = borrow_all(l2_init_metadata);
- let (peg_keeper_offer_amount, peg_keeper_return_amount) = calc_peg_keeper_swap(pool);
-
- let (l1_pool_amount, l2_pool_amount) = get_pool_amount(l2_init_metadata, true);
- l1_pool_amount = l1_pool_amount + peg_keeper_offer_amount;
- l2_pool_amount = l2_pool_amount - peg_keeper_return_amount;
-
- let (module_store, pool) = borrow_all(l2_init_metadata);
- let fee_amount = 0;
- let return_amount = if (is_l1_init_offered) {
- // 0 fee for L1 > L2
- let return_amount = get_return_amount(offer_amount, l1_pool_amount, l2_pool_amount, pool.pool_size, pool.ann);
- assert!(
- l2_pool_amount >= pool.pool_size && l1_pool_amount <= pool.pool_size,
- error::invalid_state(EL2_PRICE_TOO_LOW),
+ let (return_amount, fee_amount) =
+ safe_swap_simulation(
+ offer_metadata,
+ return_metadata,
+ offer_amount
);
- return_amount
- } else {
- let return_amount = get_return_amount(offer_amount, l2_pool_amount, l1_pool_amount, pool.pool_size, pool.ann);
- fee_amount = decimal128::mul_u64(&module_store.swap_fee_rate, return_amount);
- let return_amount = return_amount - fee_amount;
- return_amount
- };
-
+ assert!(
+ return_amount != 0,
+ error::invalid_state(EIBC_OP_INIT_PRICE_TOO_LOW)
+ );
(return_amount, fee_amount)
}
-
+
+
+## Function `swap_simulation_given_out`
+
+
+
+#[view]
+public fun swap_simulation_given_out(offer_metadata: object::Object<fungible_asset::Metadata>, return_metadata: object::Object<fungible_asset::Metadata>, return_amount: u64): (u64, u64)
+
+
+
+
+##### Implementation
+
+
+public fun swap_simulation_given_out(
+ offer_metadata: Object<Metadata>,
+ return_metadata: Object<Metadata>,
+ return_amount: u64
+): (u64, u64) acquires ModuleStore, VirtualPool {
+ let (return_amount, fee_amount) =
+ safe_swap_simulation_given_out(
+ offer_metadata,
+ return_metadata,
+ return_amount
+ );
+ assert!(
+ return_amount != (U64_MAX as u64),
+ error::invalid_state(EIBC_OP_INIT_PRICE_TOO_LOW)
+ );
+ (return_amount, fee_amount)
+}
+
+
+
@@ -782,1301 +2268,2248 @@ Event emitted when rebalance peg keeper's balances.
-
-Implementation
+##### Implementation
public fun swap_simulation_by_denom(
- offer_denom: String,
- return_denom: String,
- offer_amount: u64,
+ offer_denom: String, return_denom: String, offer_amount: u64
): (u64, u64) acquires ModuleStore, VirtualPool {
let offer_metadata = coin::denom_to_metadata(offer_denom);
let return_metadata = coin::denom_to_metadata(return_denom);
- swap_simulation(offer_metadata, return_metadata, offer_amount)
+ swap_simulation(
+ offer_metadata,
+ return_metadata,
+ offer_amount
+ )
}
-
+
-
+## Function `spot_price`
-## Function `create_pool`
+
+
+#[view]
+public fun spot_price(base_metadata: object::Object<fungible_asset::Metadata>, quote_metadata: object::Object<fungible_asset::Metadata>): bigdecimal::BigDecimal
+
-public entry fun create_pool(chain: &signer, l2_init_metadata: object::Object<fungible_asset::Metadata>, recover_velocity: decimal128::Decimal128, pool_size: u64, ann: u64, max_ratio: decimal128::Decimal128, recover_param: decimal128::Decimal128)
+##### Implementation
+
+
+public fun spot_price(
+ base_metadata: Object<Metadata>, quote_metadata: Object<Metadata>
+): BigDecimal acquires ModuleStore, VirtualPool {
+ let is_init_quote = is_init_metadata(quote_metadata);
+ let ibc_op_init_metadata = if (is_init_quote) {
+ base_metadata
+ } else {
+ quote_metadata
+ };
+
+ let virtual_pool_exists = virtual_pool_exists(ibc_op_init_metadata);
+
+ assert!(
+ virtual_pool_exists,
+ error::invalid_argument(EPOOL_NOT_FOUND)
+ );
+
+ let (init_pool_amount, ibc_op_init_pool_amount) =
+ get_pool_amount(ibc_op_init_metadata, !is_init_quote);
+ let (_, pool) = borrow_all(ibc_op_init_metadata);
+
+ let swap_amount = 1000000;
+ let ibc_op_init_return_amount =
+ get_return_amount(
+ swap_amount,
+ init_pool_amount,
+ ibc_op_init_pool_amount,
+ pool.pool_size,
+ pool.ann
+ );
+ let init_return_amount =
+ get_return_amount(
+ swap_amount,
+ ibc_op_init_pool_amount,
+ init_pool_amount,
+ pool.pool_size,
+ pool.ann
+ );
+
+ if (is_init_quote) {
+ bigdecimal::from_ratio_u64(
+ init_return_amount + swap_amount,
+ ibc_op_init_return_amount + swap_amount
+ )
+ } else {
+ bigdecimal::from_ratio_u64(
+ ibc_op_init_return_amount + swap_amount,
+ init_return_amount + swap_amount
+ )
+ }
+}
-
-Implementation
+
+## Function `get_unbond_list`
-public entry fun create_pool(
- chain: &signer,
- l2_init_metadata: Object<Metadata>,
- recover_velocity: Decimal128,
- pool_size: u64,
- ann: u64,
- max_ratio: Decimal128,
- recover_param: Decimal128,
-) acquires ModuleStore {
- assert_is_chain(chain);
- assert!(pool_size > 0, error::invalid_argument(EPOOL_SIZE));
- let constructor_ref = object::create_object(@initia_std, false);
- let extend_ref = object::generate_extend_ref(&constructor_ref);
- let pool_signer = object::generate_signer(&constructor_ref);
- let (_, timestamp) = block::get_block_info();
- move_to(
- &pool_signer,
- VirtualPool {
- extend_ref,
- recover_velocity,
- pool_size,
- max_ratio,
- recover_param,
- l1_pool_amount: pool_size,
- l2_pool_amount: pool_size,
- last_recovered_timestamp: timestamp,
- virtual_l1_balance: 0,
- virtual_l2_balance: 0,
- ann,
- active: true,
- }
+
+#[view]
+public fun get_unbond_list(account: address, start_after: option::Option<u64>, limit: u64): vector<minitswap::UnbondResponse>
+
+
+
+
+##### Implementation
+
+
+public fun get_unbond_list(
+ account: address, start_after: Option<u64>, limit: u64
+): vector<UnbondResponse> acquires ModuleStore {
+ let module_store = borrow_global<ModuleStore>(@initia_std);
+ let start_key =
+ if (option::is_some(&start_after)) {
+ generate_unbond_key(
+ account,
+ *option::borrow(&start_after) + 1
+ )
+ } else {
+ generate_unbond_key(account, 0)
+ };
+
+ if (limit > MAX_LIMIT) {
+ limit = MAX_LIMIT
+ };
+
+ let iter =
+ table::iter(
+ &module_store.unbond_wait_list,
+ option::some(start_key),
+ option::none(),
+ 1
+ );
+
+ let i = 0;
+ let res: vector<UnbondResponse> = vector[];
+ while (i < limit && table::prepare(iter)) {
+ let (_, value) = table::next<vector<u8>, UnbondEntity>(iter);
+ if (value.account != account) break;
+
+ vector::push_back(
+ &mut res,
+ UnbondResponse {
+ account: value.account,
+ share_amount: value.share_amount,
+ withdraw_amount: value.withdraw_amount,
+ release_time: value.release_time
+ }
+ );
+ };
+
+ return res
+}
+
+
+
+
+
+
+## Function `get_arb_info`
+
+
+
+#[view]
+public fun get_arb_info(id: u64): minitswap::ArbResponse
+
+
+
+
+##### Implementation
+
+
+public fun get_arb_info(id: u64): ArbResponse acquires ModuleStore, VirtualPool {
+ let module_store = borrow_global<ModuleStore>(@initia_std);
+ let pool_obj =
+ table::borrow(
+ &module_store.global_arb_batch_map,
+ table_key::encode_u64(id)
+ );
+ let pool = borrow_global<VirtualPool>(object::object_address(&*pool_obj));
+ let arb_info = table::borrow(
+ &pool.arb_batch_map,
+ table_key::encode_u64(id)
);
- let module_store = borrow_global_mut<ModuleStore>(@initia_std);
- table::add(&mut module_store.pools, l2_init_metadata, object::object_from_constructor_ref<VirtualPool>(&constructor_ref));
+ return ArbResponse {
+ ibc_op_init_metadata: pool.ibc_op_init_metadata,
+ id,
+ executed_time: arb_info.executed_time,
+ init_used: arb_info.init_used,
+ ibc_op_init_sent: arb_info.ibc_op_init_sent,
+ triggering_fee: arb_info.triggering_fee
+ }
+}
+
+
+
+
+
+
+## Function `get_arb_infos`
+
+
+
+#[view]
+public fun get_arb_infos(ibc_op_init_metadata: object::Object<fungible_asset::Metadata>, start_after: option::Option<u64>, limit: u64): vector<minitswap::ArbResponse>
+
+
+
+
+##### Implementation
+
+
+public fun get_arb_infos(
+ ibc_op_init_metadata: Object<Metadata>, start_after: Option<u64>, limit: u64
+): vector<ArbResponse> acquires ModuleStore, VirtualPool {
+ let (_, pool) = borrow_all(ibc_op_init_metadata);
+ let start_key =
+ if (option::is_some(&start_after)) {
+ table_key::encode_u64(*option::borrow(&start_after) + 1)
+ } else {
+ table_key::encode_u64(0)
+ };
+
+ if (limit > MAX_LIMIT) {
+ limit = MAX_LIMIT
+ };
+
+ let iter =
+ table::iter(
+ &pool.arb_batch_map,
+ option::some(start_key),
+ option::none(),
+ 1
+ );
+
+ let i = 0;
+ let res: vector<ArbResponse> = vector[];
+ while (i < limit && table::prepare(iter)) {
+ let (key, arb_info) = table::next<vector<u8>, ArbInfo>(iter);
+ let id = table_key::decode_u64(key);
+
+ vector::push_back(
+ &mut res,
+ ArbResponse {
+ ibc_op_init_metadata: pool.ibc_op_init_metadata,
+ id,
+ executed_time: arb_info.executed_time,
+ init_used: arb_info.init_used,
+ ibc_op_init_sent: arb_info.ibc_op_init_sent,
+ triggering_fee: arb_info.triggering_fee
+ }
+ );
+ };
+
+ return res
}
-
+
-
-
-## Function `deactivate`
+## Function `get_module_store`
-public entry fun deactivate(chain: &signer, l2_init_metadata: object::Object<fungible_asset::Metadata>)
+#[view]
+public fun get_module_store(): minitswap::ModuleStoreResponse
-
-Implementation
+##### Implementation
-public entry fun deactivate(chain: &signer, l2_init_metadata: Object<Metadata>) acquires ModuleStore, VirtualPool {
- assert_is_chain(chain);
- let module_store = borrow_global_mut<ModuleStore>(@initia_std);
- let pool_obj = table::borrow(&mut module_store.pools, l2_init_metadata);
- let pool = borrow_global_mut<VirtualPool>(object::object_address(*pool_obj));
- pool.active = false
+public fun get_module_store(): ModuleStoreResponse acquires ModuleStore {
+ let module_store = borrow_global<ModuleStore>(@initia_std);
+
+ return ModuleStoreResponse {
+ max_change_rate: module_store.max_change_rate,
+ emergency_state: module_store.emergency_state,
+ admin: module_store.admin,
+ depositor_owned_init: module_store.depositor_owned_init,
+ unbond_period: module_store.unbond_period,
+ swap_fee_rate: module_store.swap_fee_rate,
+ arb_fee_rate: module_store.arb_fee_rate,
+ trigger_fee: module_store.trigger_fee,
+ min_arb_profit: module_store.min_arb_profit,
+ ibc_timeout: module_store.ibc_timeout,
+ max_arb_batch: module_store.max_arb_batch,
+ min_arb_interval: module_store.min_arb_interval,
+ arb_batch_index: module_store.arb_batch_index
+ }
}
-
-
-
+
-## Function `activate`
+## Function `get_pools`
-public entry fun activate(chain: &signer, l2_init_metadata: object::Object<fungible_asset::Metadata>)
+#[view]
+public fun get_pools(ibc_op_init_metadata: object::Object<fungible_asset::Metadata>): minitswap::PoolsResponse
-
-Implementation
+##### Implementation
-public entry fun activate(chain: &signer, l2_init_metadata: Object<Metadata>) acquires ModuleStore, VirtualPool {
- assert_is_chain(chain);
- let module_store = borrow_global_mut<ModuleStore>(@initia_std);
- let pool_obj = table::borrow(&mut module_store.pools, l2_init_metadata);
- let pool = borrow_global_mut<VirtualPool>(object::object_address(*pool_obj));
- pool.active = true
+public fun get_pools(ibc_op_init_metadata: Object<Metadata>): PoolsResponse acquires ModuleStore {
+ let module_store = borrow_global<ModuleStore>(@initia_std);
+ let pools = table::borrow(&module_store.pools, ibc_op_init_metadata);
+ return PoolsResponse {
+ ibc_op_init_metadata,
+ ibc_op_init_denom: coin::symbol(ibc_op_init_metadata),
+ op_bridge_id: pools.op_bridge_id,
+ ibc_channel: pools.ibc_channel,
+ virtual_pool: pools.virtual_pool,
+ stableswap_pool: pools.stableswap_pool
+ }
}
-
-
-
+
-## Function `change_pool_size`
+## Function `get_pools_list`
-public entry fun change_pool_size(chain: &signer, l2_init_metadata: object::Object<fungible_asset::Metadata>, new_pool_size: u64)
+#[view]
+public fun get_pools_list(start_after: option::Option<object::Object<fungible_asset::Metadata>>, limit: u64): vector<minitswap::PoolsResponse>
-
-Implementation
+##### Implementation
-public entry fun change_pool_size(
- chain: &signer,
- l2_init_metadata: Object<Metadata>,
- new_pool_size: u64
-) acquires ModuleStore, VirtualPool {
- assert_is_chain(chain);
- assert!(new_pool_size > 0, error::invalid_argument(EPOOL_SIZE));
- let module_store = borrow_global_mut<ModuleStore>(@initia_std);
- let pool_obj = table::borrow(&mut module_store.pools, l2_init_metadata);
- let pool = borrow_global_mut<VirtualPool>(object::object_address(*pool_obj));
+public fun get_pools_list(
+ start_after: Option<Object<Metadata>>, limit: u64
+): vector<PoolsResponse> acquires ModuleStore {
+ let module_store = borrow_global<ModuleStore>(@initia_std);
- let change_rate = if (new_pool_size > pool.pool_size) {
- decimal128::from_ratio_u64(new_pool_size - pool.pool_size, pool.pool_size)
- } else {
- decimal128::from_ratio_u64(pool.pool_size - new_pool_size, pool.pool_size)
+ if (limit > MAX_LIMIT) {
+ limit = MAX_LIMIT
};
- assert!(decimal128::val(&module_store.max_change_rate) >= decimal128::val(&change_rate), error::invalid_argument(EMAX_CHANGE));
-
- if (new_pool_size < pool.pool_size) {
- /*
- Decrease size process
- 1. Change pool amount as ratio
- 2. Calculate diff, update peg keeper's balances
-
- Net Effect
- This action is same with swap L1 > L2 until pool ratio to be 5:5,
- change pool size and sell some portion of L2 at same price
- - L1 and L2 balances of peg keepers -> L1 decrease L2 increase,
- but L1 decreased amount is smaller than L2 increased amount.
- - Pool ratio doesn't change (= price not change)
- */
- let current_l1_delta = pool.pool_size - pool.l1_pool_amount;
- let current_l2_delta = pool.l2_pool_amount - pool.pool_size;
-
- let ratio = decimal128::from_ratio_u64(new_pool_size, pool.pool_size);
- pool.l1_pool_amount = decimal128::mul_u64(&ratio, pool.l1_pool_amount);
- pool.l2_pool_amount = decimal128::mul_u64(&ratio, pool.l2_pool_amount);
- pool.pool_size = new_pool_size;
-
- let l1_delta = pool.pool_size - pool.l1_pool_amount;
- let l2_delta = pool.l2_pool_amount - pool.pool_size;
-
- let net_l1_delta = current_l1_delta - l1_delta;
- let net_l2_delta = current_l2_delta - l2_delta;
-
- pool.virtual_l1_balance = pool.virtual_l1_balance + net_l1_delta;
- pool.virtual_l2_balance = pool.virtual_l2_balance + net_l2_delta;
- } else {
- /*
- Increase size process
- 1. Swap L1 > L2 to make 5:5
- 2. Change pool size
- 3. Swap back L2 > L1
- a. If L1 init balance of peg keeper is greater than 0, return it to provider
-
- Net Effect
- - L1 and L2 balances of peg keepers -> + for L1 and even for L2
- - Ratio of pool -> L2 price decrease
- */
-
- // 1. swap to make 5:5
- let l1_swap_amount = pool.pool_size - pool.l1_pool_amount;
- let l2_return_amount = pool.l2_pool_amount - pool.pool_size;
- // pool.l1_pool_amount = pool.pool_size;
- // pool.l2_pool_amount = pool.pool_size;
- pool.virtual_l1_balance = pool.virtual_l1_balance + l1_swap_amount;
- pool.virtual_l2_balance = pool.virtual_l2_balance + l2_return_amount;
-
- // 2. change pool size
- pool.l1_pool_amount = new_pool_size;
- pool.l2_pool_amount = new_pool_size;
- pool.pool_size = new_pool_size;
-
- // 3. swap back
- let return_amount = get_return_amount(l2_return_amount, pool.l2_pool_amount, pool.l1_pool_amount, pool.pool_size, pool.ann);
- pool.l2_pool_amount = pool.l2_pool_amount + l2_return_amount;
- pool.l1_pool_amount = pool.l1_pool_amount - return_amount;
- pool.virtual_l2_balance = pool.virtual_l2_balance - l2_return_amount;
-
- if (pool.virtual_l1_balance < return_amount) {
- let remain = return_amount - pool.virtual_l1_balance;
- module_store.l1_init_amount = module_store.l1_init_amount + remain;
- pool.virtual_l1_balance = 0
- } else {
- pool.virtual_l1_balance = pool.virtual_l1_balance - return_amount;
- }
- }
+ let iter = table::iter(
+ &module_store.pools,
+ option::none(),
+ start_after,
+ 2
+ );
+
+ let i = 0;
+ let res: vector<PoolsResponse> = vector[];
+ while (i < limit && table::prepare(iter)) {
+ let (ibc_op_init_metadata, pools) = table::next<Object<Metadata>, Pools>(iter);
+
+ vector::push_back(
+ &mut res,
+ PoolsResponse {
+ ibc_op_init_metadata,
+ ibc_op_init_denom: coin::symbol(ibc_op_init_metadata),
+ op_bridge_id: pools.op_bridge_id,
+ ibc_channel: pools.ibc_channel,
+ virtual_pool: pools.virtual_pool,
+ stableswap_pool: pools.stableswap_pool
+ }
+ );
+ };
+
+ return res
}
-
-
-
+
-## Function `update_module_params`
+## Function `get_pools_detail`
-public entry fun update_module_params(chain: &signer, swap_fee_rate: option::Option<decimal128::Decimal128>, max_change_rate: option::Option<decimal128::Decimal128>)
+#[view]
+public fun get_pools_detail(ibc_op_init_metadata: object::Object<fungible_asset::Metadata>): minitswap::PoolsDetailResponse
-
-Implementation
+##### Implementation
-public entry fun update_module_params(
- chain: &signer,
- swap_fee_rate: Option<Decimal128>,
- max_change_rate: Option<Decimal128>,
-) acquires ModuleStore {
- assert_is_chain(chain);
- let module_store = borrow_global_mut<ModuleStore>(@initia_std);
+public fun get_pools_detail(
+ ibc_op_init_metadata: Object<Metadata>
+): PoolsDetailResponse acquires ModuleStore, VirtualPool {
+ let module_store = borrow_global<ModuleStore>(@initia_std);
+ let pools = table::borrow(&module_store.pools, ibc_op_init_metadata);
+ let virtual_pool =
+ if (option::is_some(&pools.virtual_pool)) {
+ let vp =
+ borrow_global<VirtualPool>(
+ object::object_address(&*option::borrow(&pools.virtual_pool))
+ );
+ option::some(
+ VirtualPoolDetail {
+ pool_size: vp.pool_size,
+ recover_velocity: vp.recover_velocity,
+ max_ratio: vp.max_ratio,
+ recover_param: vp.recover_param,
+ init_pool_amount: vp.init_pool_amount,
+ ibc_op_init_pool_amount: vp.ibc_op_init_pool_amount,
+ last_recovered_timestamp: vp.last_recovered_timestamp,
+ virtual_init_balance: vp.virtual_init_balance,
+ virtual_ibc_op_init_balance: vp.virtual_ibc_op_init_balance,
+ peg_keeper_owned_ibc_op_init_balance: vp.peg_keeper_owned_ibc_op_init_balance,
+ ann: vp.ann,
+ active: vp.active
+ }
+ )
+ } else {
+ option::none()
+ };
- if (option::is_some(&swap_fee_rate)) {
- module_store.swap_fee_rate = option::extract(&mut swap_fee_rate);
- };
+ let stableswap_pool =
+ if (option::is_some(&pools.stableswap_pool)) {
+ option::some(
+ stableswap::get_pool(*option::borrow(&pools.stableswap_pool))
+ )
+ } else {
+ option::none()
+ };
- if (option::is_some(&max_change_rate)) {
- module_store.max_change_rate = option::extract(&mut max_change_rate);
- };
+ return PoolsDetailResponse {
+ ibc_op_init_metadata,
+ ibc_op_init_denom: coin::symbol(ibc_op_init_metadata),
+ op_bridge_id: pools.op_bridge_id,
+ ibc_channel: pools.ibc_channel,
+ virtual_pool: virtual_pool,
+ stableswap_pool
+ }
}
-
-
-
+
-## Function `update_pool_params`
+## Function `get_pools_detail_list`
-public entry fun update_pool_params(chain: &signer, l2_init_metadata: object::Object<fungible_asset::Metadata>, recover_velocity: option::Option<decimal128::Decimal128>, ann: option::Option<u64>, max_ratio: option::Option<decimal128::Decimal128>, recover_param: option::Option<decimal128::Decimal128>)
+#[view]
+public fun get_pools_detail_list(start_after: option::Option<object::Object<fungible_asset::Metadata>>, limit: u64): vector<minitswap::PoolsDetailResponse>
-
-Implementation
+##### Implementation
-public entry fun update_pool_params(
- chain: &signer,
- l2_init_metadata: Object<Metadata>,
- recover_velocity: Option<Decimal128>,
- ann: Option<u64>,
- max_ratio: Option<Decimal128>,
- recover_param: Option<Decimal128>,
-) acquires ModuleStore, VirtualPool {
- assert_is_chain(chain);
- let module_store = borrow_global_mut<ModuleStore>(@initia_std);
- let pool_obj = table::borrow(&mut module_store.pools, l2_init_metadata);
- let pool = borrow_global_mut<VirtualPool>(object::object_address(*pool_obj));
+public fun get_pools_detail_list(
+ start_after: Option<Object<Metadata>>, limit: u64
+): vector<PoolsDetailResponse> acquires ModuleStore, VirtualPool {
+ let module_store = borrow_global<ModuleStore>(@initia_std);
- if (option::is_some(&recover_velocity)) {
- pool.recover_velocity = option::extract(&mut recover_velocity);
+ if (limit > MAX_LIMIT) {
+ limit = MAX_LIMIT
};
- // It is okay to change ann immediately cause there are no real provider
- if (option::is_some(&ann)) {
- pool.ann = option::extract(&mut ann);
- };
+ let iter = table::iter(
+ &module_store.pools,
+ option::none(),
+ start_after,
+ 2
+ );
- if (option::is_some(&max_ratio)) {
- pool.max_ratio = option::extract(&mut max_ratio);
+ let i = 0;
+ let res: vector<PoolsDetailResponse> = vector[];
+ while (i < limit && table::prepare(iter)) {
+ let (ibc_op_init_metadata, pools) = table::next<Object<Metadata>, Pools>(iter);
+
+ let virtual_pool =
+ if (option::is_some(&pools.virtual_pool)) {
+ let vp =
+ borrow_global<VirtualPool>(
+ object::object_address(
+ &*option::borrow(&pools.virtual_pool)
+ )
+ );
+ option::some(
+ VirtualPoolDetail {
+ pool_size: vp.pool_size,
+ recover_velocity: vp.recover_velocity,
+ max_ratio: vp.max_ratio,
+ recover_param: vp.recover_param,
+ init_pool_amount: vp.init_pool_amount,
+ ibc_op_init_pool_amount: vp.ibc_op_init_pool_amount,
+ last_recovered_timestamp: vp.last_recovered_timestamp,
+ virtual_init_balance: vp.virtual_init_balance,
+ virtual_ibc_op_init_balance: vp.virtual_ibc_op_init_balance,
+ peg_keeper_owned_ibc_op_init_balance: vp.peg_keeper_owned_ibc_op_init_balance,
+ ann: vp.ann,
+ active: vp.active
+ }
+ )
+ } else {
+ option::none()
+ };
+
+ let stableswap_pool =
+ if (option::is_some(&pools.stableswap_pool)) {
+ option::some(
+ stableswap::get_pool(*option::borrow(&pools.stableswap_pool))
+ )
+ } else {
+ option::none()
+ };
+
+ vector::push_back(
+ &mut res,
+ PoolsDetailResponse {
+ ibc_op_init_metadata,
+ ibc_op_init_denom: coin::symbol(ibc_op_init_metadata),
+ op_bridge_id: pools.op_bridge_id,
+ ibc_channel: pools.ibc_channel,
+ virtual_pool: virtual_pool,
+ stableswap_pool
+ }
+ )
};
- if (option::is_some(&recover_param)) {
- pool.recover_param = option::extract(&mut recover_param);
- };
+ return res
+
}
-
-
-
+
-## Function `provide`
+## Function `unpack_unbond_response`
-public entry fun provide(account: &signer, amount: u64, min_return_amount: option::Option<u64>)
+public fun unpack_unbond_response(res: minitswap::UnbondResponse): (address, u64, u64, u64)
-
-Implementation
+##### Implementation
-public entry fun provide(account: &signer, amount: u64, min_return_amount: Option<u64>) acquires ModuleStore {
- let l1_init = primary_fungible_store::withdraw(account, l1_init_metadata(), amount);
- let share_token = provide_internal(l1_init);
- assert_min_amount(&share_token, min_return_amount);
- primary_fungible_store::deposit(signer::address_of(account), share_token);
+public fun unpack_unbond_response(res: UnbondResponse): (address, u64, u64, u64) {
+ return (res.account, res.share_amount, res.withdraw_amount, res.release_time)
}
-
-
-
+
-## Function `withdraw`
+## Function `unpack_arb_response`
-public entry fun withdraw(account: &signer, amount: u64, min_return_amount: option::Option<u64>)
+public fun unpack_arb_response(res: minitswap::ArbResponse): (object::Object<fungible_asset::Metadata>, u64, u64, u64, u64, u64)
-
-Implementation
+##### Implementation
-public entry fun withdraw(account: &signer, amount: u64, min_return_amount: Option<u64>) acquires ModuleStore {
- let share_token = primary_fungible_store::withdraw(account, share_token_metadata(), amount);
- let l1_init = withdraw_internal(share_token);
- assert_min_amount(&l1_init, min_return_amount);
- primary_fungible_store::deposit(signer::address_of(account), l1_init);
+public fun unpack_arb_response(res: ArbResponse):
+ (Object<Metadata>, u64, u64, u64, u64, u64) {
+ return (
+ res.ibc_op_init_metadata,
+ res.id,
+ res.executed_time,
+ res.init_used,
+ res.ibc_op_init_sent,
+ res.triggering_fee
+ )
}
-
+
+
+## Function `unpack_module_store_response`
-
-## Function `swap`
+
+public fun unpack_module_store_response(res: minitswap::ModuleStoreResponse): (bigdecimal::BigDecimal, bool, address, u64, u64, bigdecimal::BigDecimal, bigdecimal::BigDecimal, u64, u64, u64, u64, u64, u64)
+
-public entry fun swap(account: &signer, offer_asset_metadata: object::Object<fungible_asset::Metadata>, return_metadata: object::Object<fungible_asset::Metadata>, amount: u64, min_return_amount: option::Option<u64>)
+##### Implementation
+
+
+public fun unpack_module_store_response(
+ res: ModuleStoreResponse
+): (
+ BigDecimal,
+ bool,
+ address,
+ u64,
+ u64,
+ BigDecimal,
+ BigDecimal,
+ u64,
+ u64,
+ u64,
+ u64,
+ u64,
+ u64
+) {
+ return (
+ res.max_change_rate,
+ res.emergency_state,
+ res.admin,
+ res.depositor_owned_init,
+ res.unbond_period,
+ res.swap_fee_rate,
+ res.arb_fee_rate,
+ res.trigger_fee,
+ res.min_arb_profit,
+ res.ibc_timeout,
+ res.max_arb_batch,
+ res.min_arb_interval,
+ res.arb_batch_index
+ )
+}
-
-Implementation
+
+## Function `unpack_pools_response`
-public entry fun swap(
- account: &signer,
- offer_asset_metadata: Object<Metadata>,
- return_metadata: Object<Metadata>,
- amount: u64,
- min_return_amount: Option<u64>
-) acquires ModuleStore, VirtualPool {
- let offer_asset = primary_fungible_store::withdraw(account, offer_asset_metadata, amount);
- let return_asset = swap_internal(offer_asset, return_metadata);
- assert_min_amount(&return_asset, min_return_amount);
- primary_fungible_store::deposit(signer::address_of(account), return_asset);
+
+
+public fun unpack_pools_response(res: minitswap::PoolsResponse): (object::Object<fungible_asset::Metadata>, string::String, u64, string::String, option::Option<object::Object<minitswap::VirtualPool>>, option::Option<object::Object<stableswap::Pool>>)
+
+
+
+
+##### Implementation
+
+
+public fun unpack_pools_response(
+ res: PoolsResponse
+): (
+ Object<Metadata>,
+ String,
+ u64,
+ String,
+ Option<Object<VirtualPool>>,
+ Option<Object<Pool>>
+) {
+ return (
+ res.ibc_op_init_metadata,
+ res.ibc_op_init_denom,
+ res.op_bridge_id,
+ res.ibc_channel,
+ res.virtual_pool,
+ res.stableswap_pool
+ )
}
-
+
+
+## Function `unpack_pools_detail_response`
+
-
-## Function `rebalance`
+public fun unpack_pools_detail_response(res: minitswap::PoolsDetailResponse): (object::Object<fungible_asset::Metadata>, string::String, u64, string::String, option::Option<minitswap::VirtualPoolDetail>, option::Option<stableswap::PoolResponse>)
+
-public entry fun rebalance(account: &signer, l2_asset_metadata: object::Object<fungible_asset::Metadata>, amount: u64, min_return_amount: option::Option<u64>)
+##### Implementation
+
+
+public fun unpack_pools_detail_response(
+ res: PoolsDetailResponse
+): (
+ Object<Metadata>,
+ String,
+ u64,
+ String,
+ Option<VirtualPoolDetail>,
+ Option<stableswap::PoolResponse>
+) {
+ let PoolsDetailResponse {
+ ibc_op_init_metadata,
+ ibc_op_init_denom,
+ op_bridge_id,
+ ibc_channel,
+ virtual_pool,
+ stableswap_pool
+ } = res;
+ return (
+ ibc_op_init_metadata,
+ ibc_op_init_denom,
+ op_bridge_id,
+ ibc_channel,
+ virtual_pool,
+ stableswap_pool
+ )
+}
-
-Implementation
+
+## Function `unpack_virtual_pool_detail`
-public entry fun rebalance(
- account: &signer,
- l2_asset_metadata: Object<Metadata>,
- amount: u64,
- min_return_amount: Option<u64>
-) acquires ModuleStore, VirtualPool {
- let l1_init = primary_fungible_store::withdraw(account, l1_init_metadata(), amount);
- let l2_init = rebalance_internal(l1_init, l2_asset_metadata);
- assert_min_amount(&l2_init, min_return_amount);
- primary_fungible_store::deposit(signer::address_of(account), l2_init);
-}
+
+
+public fun unpack_virtual_pool_detail(res: minitswap::VirtualPoolDetail): (u64, bigdecimal::BigDecimal, bigdecimal::BigDecimal, bigdecimal::BigDecimal, u64, u64, u64, u64, u64, u64, u64, bool)
-
+##### Implementation
-
-## Function `provide_internal`
+public fun unpack_virtual_pool_detail(
+ res: VirtualPoolDetail
+): (u64, BigDecimal, BigDecimal, BigDecimal, u64, u64, u64, u64, u64, u64, u64, bool) {
+ return (
+ res.pool_size,
+ res.recover_velocity,
+ res.max_ratio,
+ res.recover_param,
+ res.init_pool_amount,
+ res.ibc_op_init_pool_amount,
+ res.last_recovered_timestamp,
+ res.virtual_init_balance,
+ res.virtual_ibc_op_init_balance,
+ res.peg_keeper_owned_ibc_op_init_balance,
+ res.ann,
+ res.active
+ )
+}
+
+
+
+
+## Function `create_pool`
+
-public fun provide_internal(l1_init: fungible_asset::FungibleAsset): fungible_asset::FungibleAsset
+
+public entry fun create_pool(chain: &signer, ibc_op_init_metadata: object::Object<fungible_asset::Metadata>, recover_velocity: bigdecimal::BigDecimal, pool_size: u64, ann: u64, max_ratio: bigdecimal::BigDecimal, recover_param: bigdecimal::BigDecimal, vm_type: u8, hook_contract: string::String, op_bridge_id: u64, ibc_channel: string::String)
-
-Implementation
+##### Implementation
+
+
+public entry fun create_pool(
+ chain: &signer,
+ ibc_op_init_metadata: Object<Metadata>,
+ recover_velocity: BigDecimal,
+ pool_size: u64,
+ ann: u64,
+ max_ratio: BigDecimal,
+ recover_param: BigDecimal,
+ vm_type: u8,
+ hook_contract: String,
+ op_bridge_id: u64,
+ ibc_channel: String
+) acquires ModuleStore {
+ assert_is_chain(chain, false);
+ assert!(
+ pool_size > 0,
+ error::invalid_argument(EPOOL_SIZE)
+ );
+ let constructor_ref = object::create_object(@initia_std, false);
+ let extend_ref = object::generate_extend_ref(&constructor_ref);
+ let pool_signer = object::generate_signer(&constructor_ref);
+ let (_, timestamp) = block::get_block_info();
+
+ assert!(
+ vm_type == MOVE || vm_type == COSMWASM,
+ error::invalid_argument(EVM_TYPE)
+ );
+ check_bridge_info(
+ op_bridge_id,
+ ibc_channel,
+ ibc_op_init_metadata
+ );
-public fun provide_internal(l1_init: FungibleAsset): FungibleAsset acquires ModuleStore {
- assert!(is_l1_init(&l1_init), error::invalid_argument(ENOT_L1_INIT));
- let provide_amount = fungible_asset::amount(&l1_init);
+ move_to(
+ &pool_signer,
+ VirtualPool {
+ ibc_op_init_metadata,
+ extend_ref,
+ recover_velocity,
+ pool_size,
+ max_ratio,
+ recover_param,
+ init_pool_amount: pool_size,
+ ibc_op_init_pool_amount: pool_size,
+ last_recovered_timestamp: timestamp,
+ virtual_init_balance: 0,
+ virtual_ibc_op_init_balance: 0,
+ peg_keeper_owned_ibc_op_init_balance: 0,
+ ann,
+ active: true,
+ op_bridge_id,
+ ibc_channel,
+ vm_type,
+ hook_contract,
+ arb_batch_map: table::new()
+ }
+ );
let module_store = borrow_global_mut<ModuleStore>(@initia_std);
- let total_share = total_share();
- let share_amount = if (total_share == 0) {
- provide_amount
- } else {
- mul_div(provide_amount, (total_share as u64), module_store.l1_init_amount)
- };
- module_store.l1_init_amount = module_store.l1_init_amount + provide_amount;
+ let pools =
+ borrow_pools_with_default(
+ module_store,
+ ibc_op_init_metadata,
+ op_bridge_id,
+ ibc_channel
+ );
- let module_addr = object::address_from_extend_ref(&module_store.extend_ref);
- primary_fungible_store::deposit(module_addr, l1_init);
- event::emit<ProvideEvent>(
- ProvideEvent {
- provide_amount,
- share_amount,
- },
+ assert!(
+ option::is_none(&pools.virtual_pool),
+ error::already_exists(EVIRTUAL_POOL_EXISTS)
);
- coin::mint(&module_store.mint_cap, share_amount)
+ pools.virtual_pool = option::some(
+ object::object_from_constructor_ref<VirtualPool>(&constructor_ref)
+ );
+
+ event::emit(
+ CreatePoolEvent {
+ ibc_op_init_metadata,
+ recover_velocity,
+ pool_size,
+ ann,
+ max_ratio,
+ recover_param
+ }
+ )
}
-
+
-
+## Function `set_emergency_state`
-## Function `withdraw_internal`
-
-public fun withdraw_internal(share_token: fungible_asset::FungibleAsset): fungible_asset::FungibleAsset
+public entry fun set_emergency_state(chain: &signer, state: bool)
-
-Implementation
+##### Implementation
-public fun withdraw_internal(share_token: FungibleAsset): FungibleAsset acquires ModuleStore {
+public entry fun set_emergency_state(chain: &signer, state: bool) acquires ModuleStore {
+ assert_is_chain(chain, true);
let module_store = borrow_global_mut<ModuleStore>(@initia_std);
- let share_token_metadata = fungible_asset::metadata_from_asset(&share_token);
- assert!(share_token_metadata == share_token_metadata(), error::invalid_argument(ENOT_SHARE_TOKEN));
- let share_amount = fungible_asset::amount(&share_token);
- let total_share = total_share();
- let withdraw_amount = mul_div(share_amount, module_store.l1_init_amount, total_share);
- module_store.l1_init_amount = module_store.l1_init_amount - withdraw_amount;
-
- coin::burn(&module_store.burn_cap, share_token);
- let module_signer = object::generate_signer_for_extending(&module_store.extend_ref);
- event::emit<WithdrawEvent>(
- WithdrawEvent {
- withdraw_amount,
- share_amount,
- },
- );
- primary_fungible_store::withdraw(&module_signer, l1_init_metadata(), withdraw_amount)
+ module_store.emergency_state = state
}
-
+
+
+## Function `deactivate`
-
-## Function `swap_internal`
+public entry fun deactivate(chain: &signer, ibc_op_init_metadata: object::Object<fungible_asset::Metadata>)
+
-public fun swap_internal(offer_asset: fungible_asset::FungibleAsset, return_metadata: object::Object<fungible_asset::Metadata>): fungible_asset::FungibleAsset
+
+##### Implementation
+
+
+public entry fun deactivate(
+ chain: &signer, ibc_op_init_metadata: Object<Metadata>
+) acquires ModuleStore, VirtualPool {
+ assert_is_chain(chain, true);
+ let module_store = borrow_global_mut<ModuleStore>(@initia_std);
+ let pools = table::borrow(&mut module_store.pools, ibc_op_init_metadata);
+ let pool =
+ borrow_global_mut<VirtualPool>(
+ object::object_address(&*option::borrow(&pools.virtual_pool))
+ );
+ pool.active = false
+}
-
-Implementation
+
+## Function `activate`
-public fun swap_internal(
- offer_asset: FungibleAsset,
- return_metadata: Object<Metadata>,
-): FungibleAsset acquires ModuleStore, VirtualPool {
- let (_, timestamp) = block::get_block_info();
- let is_l1_init_offered = is_l1_init(&offer_asset);
- let offer_metadata = fungible_asset::metadata_from_asset(&offer_asset);
- let (module_store, pool, module_signer, pool_signer) = if(is_l1_init_offered) {
- borrow_all_mut(return_metadata)
- } else {
- borrow_all_mut(offer_metadata)
- };
- assert!(pool.active, error::invalid_state(EINACTIVE));
- let (peg_keeper_offer_amount, peg_keeper_return_amount) = calc_peg_keeper_swap(pool);
- pool.l1_pool_amount = pool.l1_pool_amount + peg_keeper_offer_amount;
- pool.l2_pool_amount = pool.l2_pool_amount - peg_keeper_return_amount;
- pool.virtual_l1_balance = pool.virtual_l1_balance + peg_keeper_offer_amount;
- pool.virtual_l2_balance = pool.virtual_l2_balance + peg_keeper_return_amount;
- pool.last_recovered_timestamp = timestamp;
- let module_addr = signer::address_of(&module_signer);
- let pool_addr = signer::address_of(&pool_signer);
+public entry fun activate(chain: &signer, ibc_op_init_metadata: object::Object<fungible_asset::Metadata>)
+
- // user swap
- let offer_amount = fungible_asset::amount(&offer_asset);
- let fee_amount = 0;
- let return_asset = if (is_l1_init_offered) {
- primary_fungible_store::deposit(module_addr, offer_asset);
- // 0 fee for L1 > L2
- let return_amount = get_return_amount(offer_amount, pool.l1_pool_amount, pool.l2_pool_amount, pool.pool_size, pool.ann);
- pool.l1_pool_amount = pool.l1_pool_amount + offer_amount;
- pool.l2_pool_amount = pool.l2_pool_amount - return_amount;
- assert!(
- pool.l2_pool_amount >= pool.pool_size && pool.l1_pool_amount <= pool.pool_size,
- error::invalid_state(EL2_PRICE_TOO_LOW),
- );
- primary_fungible_store::withdraw(&pool_signer, return_metadata, return_amount)
- } else {
- primary_fungible_store::deposit(pool_addr, offer_asset);
- let return_amount = get_return_amount(offer_amount, pool.l2_pool_amount, pool.l1_pool_amount, pool.pool_size, pool.ann);
- fee_amount = decimal128::mul_u64(&module_store.swap_fee_rate, return_amount);
- module_store.l1_init_amount = module_store.l1_init_amount + fee_amount;
- pool.l1_pool_amount = pool.l1_pool_amount - return_amount;
- pool.l2_pool_amount = pool.l2_pool_amount + offer_amount;
- let return_amount = return_amount - fee_amount;
- primary_fungible_store::withdraw(&module_signer, return_metadata, return_amount)
- };
- event::emit<SwapEvent>(
- SwapEvent {
- offer_coin: offer_metadata,
- return_coin: return_metadata,
- peg_keeper_offer_amount, // always l1 init
- peg_keeper_return_amount, // always l2 init
- offer_amount,
- return_amount: fungible_asset::amount(&return_asset),
- fee_amount, // always l1 init
- },
- );
- return_asset
+##### Implementation
+
+
+public entry fun activate(
+ chain: &signer, ibc_op_init_metadata: Object<Metadata>
+) acquires ModuleStore, VirtualPool {
+ assert_is_chain(chain, true);
+ let module_store = borrow_global_mut<ModuleStore>(@initia_std);
+ let pools = table::borrow(&mut module_store.pools, ibc_op_init_metadata);
+ let pool =
+ borrow_global_mut<VirtualPool>(
+ object::object_address(&*option::borrow(&pools.virtual_pool))
+ );
+ pool.active = true
}
-
-
-
+
-## Function `rebalance_internal`
+## Function `change_pool_size`
-public fun rebalance_internal(l1_init: fungible_asset::FungibleAsset, l2_init_metadata: object::Object<fungible_asset::Metadata>): fungible_asset::FungibleAsset
+public entry fun change_pool_size(chain: &signer, ibc_op_init_metadata: object::Object<fungible_asset::Metadata>, new_pool_size: u64)
-
-Implementation
+##### Implementation
-public fun rebalance_internal(
- l1_init: FungibleAsset,
- l2_init_metadata: Object<Metadata>,
-): FungibleAsset acquires ModuleStore, VirtualPool {
- assert!(is_l1_init(&l1_init), error::invalid_argument(ENOT_L1_INIT));
- let (module_store, pool, module_signer, pool_signer) = borrow_all_mut(l2_init_metadata);
- let amount = fungible_asset::amount(&l1_init);
- let fee_amount = decimal128::mul_u64(&module_store.swap_fee_rate, amount);
- module_store.l1_init_amount = module_store.l1_init_amount + fee_amount;
- let offer_amount = amount - fee_amount;
- assert!(offer_amount <= pool.virtual_l1_balance, error::invalid_argument(ENOT_ENOUGH_BALANCE));
- let return_amount = mul_div(offer_amount, pool.virtual_l2_balance, pool.virtual_l1_balance);
-
- pool.virtual_l1_balance = pool.virtual_l1_balance - offer_amount;
- pool.virtual_l2_balance = pool.virtual_l2_balance - return_amount;
- primary_fungible_store::deposit(signer::address_of(&module_signer), l1_init);
-
- event::emit<RebalanceEvent>(
- RebalanceEvent {
- offer_coin: l1_init_metadata(), // always l1 init
- return_coin: l2_init_metadata, // always l2 init
- offer_amount: amount,
- return_amount,
- fee_amount,
- },
+public entry fun change_pool_size(
+ chain: &signer, ibc_op_init_metadata: Object<Metadata>, new_pool_size: u64
+) acquires ModuleStore, VirtualPool {
+ assert_is_chain(chain, false);
+ assert!(
+ new_pool_size > 0,
+ error::invalid_argument(EPOOL_SIZE)
);
- primary_fungible_store::withdraw(&pool_signer, l2_init_metadata, return_amount)
+ let module_store = borrow_global_mut<ModuleStore>(@initia_std);
+ let pools = table::borrow(&mut module_store.pools, ibc_op_init_metadata);
+ let pool =
+ borrow_global_mut<VirtualPool>(
+ object::object_address(&*option::borrow(&pools.virtual_pool))
+ );
+
+ let change_rate =
+ if (new_pool_size > pool.pool_size) {
+ bigdecimal::from_ratio_u64(
+ new_pool_size - pool.pool_size,
+ pool.pool_size
+ )
+ } else {
+ bigdecimal::from_ratio_u64(
+ pool.pool_size - new_pool_size,
+ pool.pool_size
+ )
+ };
+
+ assert!(
+ bigdecimal::ge(module_store.max_change_rate, change_rate),
+ error::invalid_argument(EMAX_CHANGE)
+ );
+
+ let depositor_owned_init_increase =
+ if (new_pool_size < pool.pool_size) {
+ /*
+ Decrease size process
+ 1. Change pool amount as ratio
+ 2. Calculate diff, update peg keeper's balances
+
+ Net Effect
+ This action is same with swap INIT > ibc op INIT until pool ratio to be 5:5,
+ change pool size and sell some portion of ibc op INIT at same price
+ - INIT and ibc op INIT balances of peg keepers -> INIT decrease ibc op INIT increase,
+ but INIT decreased amount is smaller than ibc op INIT increased amount.
+ - Pool ratio doesn't change (= price not change)
+ */
+ let current_init_delta = pool.pool_size - pool.init_pool_amount;
+ let current_ibc_op_init_delta =
+ pool.ibc_op_init_pool_amount - pool.pool_size;
+
+ let ratio = bigdecimal::from_ratio_u64(new_pool_size, pool.pool_size);
+ pool.init_pool_amount = bigdecimal::mul_by_u64_truncate(
+ ratio, pool.init_pool_amount
+ );
+ pool.ibc_op_init_pool_amount = bigdecimal::mul_by_u64_truncate(
+ ratio,
+ pool.ibc_op_init_pool_amount
+ );
+ pool.pool_size = new_pool_size;
+
+ let init_delta = pool.pool_size - pool.init_pool_amount;
+ let ibc_op_init_delta = pool.ibc_op_init_pool_amount - pool.pool_size;
+
+ let net_init_delta = current_init_delta - init_delta;
+ let net_ibc_op_init_delta = current_ibc_op_init_delta
+ - ibc_op_init_delta;
+
+ pool.virtual_init_balance = pool.virtual_init_balance + net_init_delta;
+ pool.virtual_ibc_op_init_balance = pool.virtual_ibc_op_init_balance
+ + net_ibc_op_init_delta;
+ pool.peg_keeper_owned_ibc_op_init_balance = pool.peg_keeper_owned_ibc_op_init_balance
+ + net_ibc_op_init_delta;
+ 0
+ } else {
+ /*
+ Increase size process
+ 1. Swap INIT > ibc init INIT to make 5:5
+ 2. Change pool size
+ 3. Swap back ibc init INIT > INIT
+ a. If INIT init balance of peg keeper is greater than 0, return it to provider
+
+ Net Effect
+ - INIT and ibc init INIT balances of peg keepers -> + for INIT and even for ibc init INIT
+ - Ratio of pool -> ibc init INIT price decrease
+ */
+
+ // 1. swap to make 5:5
+ let init_swap_amount = pool.pool_size - pool.init_pool_amount;
+ let ibc_op_init_swap_amount = pool.ibc_op_init_pool_amount
+ - pool.pool_size;
+ // pool.init_pool_amount = pool.pool_size;
+ // pool.ibc_op_init_pool_amount = pool.pool_size;
+ pool.virtual_init_balance = pool.virtual_init_balance
+ + init_swap_amount;
+ pool.virtual_ibc_op_init_balance = pool.virtual_ibc_op_init_balance
+ + ibc_op_init_swap_amount;
+ pool.peg_keeper_owned_ibc_op_init_balance = pool.peg_keeper_owned_ibc_op_init_balance
+ + ibc_op_init_swap_amount;
+
+ // 2. change pool size
+ pool.init_pool_amount = new_pool_size;
+ pool.ibc_op_init_pool_amount = new_pool_size;
+ pool.pool_size = new_pool_size;
+
+ // 3. swap back
+ let return_amount =
+ get_return_amount(
+ ibc_op_init_swap_amount,
+ pool.ibc_op_init_pool_amount,
+ pool.init_pool_amount,
+ pool.pool_size,
+ pool.ann
+ );
+ pool.ibc_op_init_pool_amount = pool.ibc_op_init_pool_amount
+ + ibc_op_init_swap_amount;
+ pool.init_pool_amount = pool.init_pool_amount - return_amount;
+ pool.virtual_ibc_op_init_balance = pool.virtual_ibc_op_init_balance
+ - ibc_op_init_swap_amount;
+ pool.peg_keeper_owned_ibc_op_init_balance = pool.peg_keeper_owned_ibc_op_init_balance
+ - ibc_op_init_swap_amount;
+
+ if (pool.virtual_init_balance < return_amount) {
+ let remain = return_amount - pool.virtual_init_balance;
+ module_store.depositor_owned_init = module_store.depositor_owned_init
+ + remain;
+ pool.virtual_init_balance = 0;
+ remain
+ } else {
+ pool.virtual_init_balance = pool.virtual_init_balance
+ - return_amount;
+ 0
+ }
+ };
+
+ event::emit(
+ ChangePoolSizeEvent {
+ ibc_op_init_metadata,
+ pool_size: new_pool_size,
+ depositor_owned_init_increase
+ }
+ )
}
-
-
-
+
-## Function `borrow_all_mut`
+## Function `update_module_params`
-fun borrow_all_mut(metadata: object::Object<fungible_asset::Metadata>): (&mut minitswap::ModuleStore, &mut minitswap::VirtualPool, signer, signer)
+public entry fun update_module_params(chain: &signer, max_change_rate: option::Option<bigdecimal::BigDecimal>, admin: option::Option<address>, unbond_period: option::Option<u64>, swap_fee_rate: option::Option<bigdecimal::BigDecimal>, arb_fee_rate: option::Option<bigdecimal::BigDecimal>, trigger_fee: option::Option<u64>, min_arb_profit: option::Option<u64>, ibc_timeout: option::Option<u64>, max_arb_batch: option::Option<u64>, min_arb_interval: option::Option<u64>)
-
-Implementation
+##### Implementation
-inline fun borrow_all_mut(metadata: Object<Metadata>): (&mut ModuleStore, &mut VirtualPool, signer, signer) acquires ModuleStore, VirtualPool {
+public entry fun update_module_params(
+ chain: &signer,
+ max_change_rate: Option<BigDecimal>,
+ admin: Option<address>,
+ unbond_period: Option<u64>,
+ swap_fee_rate: Option<BigDecimal>,
+ arb_fee_rate: Option<BigDecimal>,
+ trigger_fee: Option<u64>,
+ min_arb_profit: Option<u64>,
+ ibc_timeout: Option<u64>,
+ max_arb_batch: Option<u64>,
+ min_arb_interval: Option<u64>
+) acquires ModuleStore {
+ assert_is_chain(chain, false);
let module_store = borrow_global_mut<ModuleStore>(@initia_std);
- let module_signer = object::generate_signer_for_extending(&module_store.extend_ref);
- let pool_addr = object::object_address(*table::borrow(&module_store.pools, metadata));
- let pool = borrow_global_mut<VirtualPool>(pool_addr);
- let pool_signer = object::generate_signer_for_extending(&pool.extend_ref);
- (module_store, pool, module_signer, pool_signer)
-}
-
-
-
-
+ if (option::is_some(&max_change_rate)) {
+ module_store.max_change_rate = option::extract(&mut max_change_rate);
+ };
-
+ if (option::is_some(&admin)) {
+ module_store.admin = option::extract(&mut admin);
+ };
-## Function `borrow_all`
+ if (option::is_some(&unbond_period)) {
+ module_store.unbond_period = option::extract(&mut unbond_period);
+ };
+ if (option::is_some(&swap_fee_rate)) {
+ module_store.swap_fee_rate = option::extract(&mut swap_fee_rate);
+ };
+ if (option::is_some(&arb_fee_rate)) {
+ module_store.arb_fee_rate = option::extract(&mut arb_fee_rate);
+ };
-fun borrow_all(metadata: object::Object<fungible_asset::Metadata>): (&minitswap::ModuleStore, &minitswap::VirtualPool)
-
+ if (option::is_some(&trigger_fee)) {
+ module_store.trigger_fee = option::extract(&mut trigger_fee);
+ };
+ if (option::is_some(&min_arb_profit)) {
+ module_store.min_arb_profit = option::extract(&mut min_arb_profit);
+ };
+ if (option::is_some(&ibc_timeout)) {
+ module_store.ibc_timeout = option::extract(&mut ibc_timeout);
+ };
-
-Implementation
+ if (option::is_some(&max_arb_batch)) {
+ module_store.max_arb_batch = option::extract(&mut max_arb_batch);
+ };
+ if (option::is_some(&min_arb_interval)) {
+ module_store.min_arb_interval = option::extract(&mut min_arb_interval);
+ };
-inline fun borrow_all(metadata: Object<Metadata>): (&ModuleStore, &VirtualPool) acquires ModuleStore, VirtualPool {
- let module_store = borrow_global<ModuleStore>(@initia_std);
- let pool_addr = object::object_address(*table::borrow(&module_store.pools, metadata));
- let pool = borrow_global<VirtualPool>(pool_addr);
- (module_store, pool)
+ assert!(
+ module_store.min_arb_profit > module_store.trigger_fee,
+ error::invalid_argument(ESMALL_ARB_PROFIT)
+ )
}
-
-
-
+
-## Function `calc_peg_keeper_swap`
+## Function `update_pool_params`
-fun calc_peg_keeper_swap(pool: &minitswap::VirtualPool): (u64, u64)
+public entry fun update_pool_params(chain: &signer, ibc_op_init_metadata: object::Object<fungible_asset::Metadata>, recover_velocity: option::Option<bigdecimal::BigDecimal>, ann: option::Option<u64>, max_ratio: option::Option<bigdecimal::BigDecimal>, recover_param: option::Option<bigdecimal::BigDecimal>, hook_contract: option::Option<string::String>)
-
-Implementation
+##### Implementation
+
+
+public entry fun update_pool_params(
+ chain: &signer,
+ ibc_op_init_metadata: Object<Metadata>,
+ recover_velocity: Option<BigDecimal>,
+ ann: Option<u64>,
+ max_ratio: Option<BigDecimal>,
+ recover_param: Option<BigDecimal>,
+ hook_contract: Option<String>
+) acquires ModuleStore, VirtualPool {
+ assert_is_chain(chain, false);
+ let module_store = borrow_global_mut<ModuleStore>(@initia_std);
+ let pools = table::borrow(&mut module_store.pools, ibc_op_init_metadata);
+ let pool =
+ borrow_global_mut<VirtualPool>(
+ object::object_address(&*option::borrow(&pools.virtual_pool))
+ );
+
+ if (option::is_some(&recover_velocity)) {
+ pool.recover_velocity = option::extract(&mut recover_velocity);
+ };
+ // It is okay to change ann immediately cause there are no real provider
+ if (option::is_some(&ann)) {
+ pool.ann = option::extract(&mut ann);
+ };
-inline fun calc_peg_keeper_swap(pool: &VirtualPool): (u64, u64) acquires ModuleStore, VirtualPool {
- let (_, timestamp) = block::get_block_info();
+ if (option::is_some(&max_ratio)) {
+ pool.max_ratio = option::extract(&mut max_ratio);
+ };
- let imbalance = decimal128::from_ratio_u64(
- pool.virtual_l2_balance + pool.l2_pool_amount - pool.pool_size, // same with real l2 balance
- pool.pool_size,
- );
- // Peg keeper swap
- let r_fr = get_fully_recovered_ratio(&imbalance, &pool.max_ratio, &pool.recover_param);
- let current_ratio = decimal128::from_ratio_u64(pool.l2_pool_amount, pool.l1_pool_amount + pool.l2_pool_amount);
- let time_diff = timestamp - pool.last_recovered_timestamp;
- if (decimal128::val(¤t_ratio) > decimal128::val(&r_fr) && time_diff != 0) {
- let (x_fr, _) = get_fully_recovered_pool_amounts(pool.pool_size, &r_fr, pool.ann);
- let max_recover_amount = decimal128::mul_u64(&pool.recover_velocity, time_diff);
- let swap_amount_to_reach_fr = x_fr - pool.l1_pool_amount;
- let swap_amount = if (swap_amount_to_reach_fr < max_recover_amount) {
- swap_amount_to_reach_fr
- } else {
- max_recover_amount
- };
+ if (option::is_some(&recover_param)) {
+ pool.recover_param = option::extract(&mut recover_param);
+ };
- let return_amount = get_return_amount(swap_amount, pool.l1_pool_amount, pool.l2_pool_amount, pool.pool_size, pool.ann);
+ if (option::is_some(&hook_contract)) {
+ pool.hook_contract = option::extract(&mut hook_contract);
+ };
- (swap_amount, return_amount)
- } else {
- (0, 0)
- }
+ event::emit(
+ UpdatePoolParamsEvent {
+ ibc_op_init_metadata,
+ recover_velocity,
+ ann,
+ max_ratio,
+ recover_param,
+ hook_contract
+ }
+ )
}
-
-
-
+
-## Function `l1_init_metadata`
+## Function `provide`
-fun l1_init_metadata(): object::Object<fungible_asset::Metadata>
+public entry fun provide(account: &signer, amount: u64, min_return_amount: option::Option<u64>)
-
-Implementation
+##### Implementation
-fun l1_init_metadata(): Object<Metadata> {
- let addr = object::create_object_address(@initia_std, b"uinit");
- object::address_to_object<Metadata>(addr)
+public entry fun provide(
+ account: &signer, amount: u64, min_return_amount: Option<u64>
+) acquires ModuleStore {
+ let init = primary_fungible_store::withdraw(account, init_metadata(), amount);
+ let share_token = provide_internal(init);
+ assert_min_amount(&share_token, min_return_amount);
+ primary_fungible_store::deposit(signer::address_of(account), share_token);
}
-
-
-
+
-## Function `share_token_metadata`
+## Function `unbond`
-fun share_token_metadata(): object::Object<fungible_asset::Metadata>
+public entry fun unbond(account: &signer, amount: u64)
-
-Implementation
+##### Implementation
-fun share_token_metadata(): Object<Metadata> {
- let addr = object::create_object_address(@initia_std, SYMBOL);
- object::address_to_object<Metadata>(addr)
+public entry fun unbond(account: &signer, amount: u64) acquires ModuleStore {
+ let share_token =
+ primary_fungible_store::withdraw(
+ account,
+ share_token_metadata(),
+ amount
+ );
+ unbond_internal(account, share_token);
}
-
-
-
+
-## Function `total_share`
+## Function `withdraw_unbond`
-fun total_share(): u64
+public entry fun withdraw_unbond(account: &signer, release_time: u64)
-
-Implementation
+##### Implementation
-fun total_share(): u64 {
- let supply = fungible_asset::supply(share_token_metadata());
- (*option::borrow(&supply) as u64)
-}
-
-
+public entry fun withdraw_unbond(account: &signer, release_time: u64) acquires ModuleStore {
+ let addr = signer::address_of(account);
+ let module_store = borrow_global_mut<ModuleStore>(@initia_std);
+ // check emergency
+ assert!(
+ !module_store.emergency_state,
+ error::invalid_state(EEMERGENCY)
+ );
-
+ // remove unbond entity
+ let key = generate_unbond_key(addr, release_time);
+ let UnbondEntity { account: _, share_amount, withdraw_amount, release_time } =
+ table::remove(&mut module_store.unbond_wait_list, key);
-
+ // check release time
+ let (_, timestamp) = block::get_block_info();
+ assert!(
+ timestamp >= release_time,
+ error::invalid_state(ERELEASE_TIME)
+ );
-## Function `assert_is_chain`
+ // release init
+ let module_signer =
+ object::generate_signer_for_extending(&module_store.extend_ref);
+ primary_fungible_store::transfer(
+ &module_signer,
+ init_metadata(),
+ addr,
+ withdraw_amount
+ );
+ event::emit(
+ WithdrawUnbondEvent {
+ account: addr,
+ share_amount,
+ withdraw_amount,
+ release_time
+ }
+ );
+}
+
-fun assert_is_chain(_account: &signer)
-
+
+## Function `swap`
-
-Implementation
-fun assert_is_chain(_account: &signer) {
- // let addr = signer::address_of(account);
- // assert!(addr == @initia_std, error::permission_denied(ENOT_CHAIN));
-}
+public entry fun swap(account: &signer, offer_asset_metadata: object::Object<fungible_asset::Metadata>, return_asset_metadata: object::Object<fungible_asset::Metadata>, amount: u64, min_return_amount: option::Option<u64>)
-
-
-
+##### Implementation
-## Function `mul_div`
+public entry fun swap(
+ account: &signer,
+ offer_asset_metadata: Object<Metadata>,
+ return_asset_metadata: Object<Metadata>,
+ amount: u64,
+ min_return_amount: Option<u64>
+) acquires ModuleStore, VirtualPool {
+ let offer_asset =
+ primary_fungible_store::withdraw(
+ account,
+ offer_asset_metadata,
+ amount
+ );
+ let return_asset = swap_internal(offer_asset, return_asset_metadata);
+ assert_min_amount(&return_asset, min_return_amount);
-fun mul_div(a: u64, b: u64, c: u64): u64
+ primary_fungible_store::deposit(signer::address_of(account), return_asset);
+}
-
-Implementation
+
+## Function `finalize_arb`
-fun mul_div(a: u64, b: u64, c: u64): u64 {
- let a = (a as u128);
- let b = (b as u128);
- let c = (c as u128);
- (a * b / c as u64)
-}
-
+public entry fun finalize_arb(account: &signer, arb_index: u64, output_index: u64, withdrawal_proofs: vector<string::String>, sender: address, sequence: u64, version: string::String, state_root: string::String, storage_root: string::String, latest_block_hash: string::String)
+
-
-
-## Function `is_l1_init`
+##### Implementation
+public entry fun finalize_arb(
+ account: &signer,
+ arb_index: u64,
+ output_index: u64,
+ withdrawal_proofs: vector<String>,
+ sender: address,
+ sequence: u64,
+ version: String,
+ state_root: String,
+ storage_root: String,
+ latest_block_hash: String
+) acquires ModuleStore, VirtualPool {
+ // check arb info
+ let module_store = borrow_global<ModuleStore>(@initia_std);
+ let pool_obj =
+ table::borrow(
+ &module_store.global_arb_batch_map,
+ table_key::encode_u64(arb_index)
+ );
+ let pool = borrow_global<VirtualPool>(object::object_address(&*pool_obj));
+ let arb_info =
+ table::borrow(
+ &pool.arb_batch_map,
+ table_key::encode_u64(arb_index)
+ );
-fun is_l1_init(l1_init: &fungible_asset::FungibleAsset): bool
+ // execute finalize token withdrawal
+ let pool_signer = object::generate_signer_for_extending(&pool.extend_ref);
+ let withdrawal_msg =
+ generate_finalize_token_withdrawal_msg(
+ pool.op_bridge_id,
+ output_index,
+ withdrawal_proofs,
+ sender,
+ signer::address_of(&pool_signer),
+ sequence,
+ string::utf8(b"uinit"),
+ arb_info.ibc_op_init_sent,
+ version,
+ state_root,
+ storage_root,
+ latest_block_hash
+ );
+ cosmos::stargate(&pool_signer, withdrawal_msg);
+
+ // execute hook
+ let module_signer =
+ object::generate_signer_for_extending(&module_store.extend_ref);
+ cosmos::move_execute(
+ &module_signer,
+ @initia_std,
+ string::utf8(b"minitswap"),
+ string::utf8(b"finalize_arb_hook"),
+ vector[],
+ vector[
+ bcs::to_bytes(&arb_index),
+ bcs::to_bytes(&signer::address_of(account))
+ ]
+ );
+}
-
-Implementation
+
+## Function `finalize_arb_hook`
-fun is_l1_init(l1_init: &FungibleAsset): bool {
- let fa_metadata = fungible_asset::metadata_from_asset(l1_init);
- is_l1_init_metadata(fa_metadata)
-}
-
+public entry fun finalize_arb_hook(module_signer: &signer, arb_index: u64, executor: address)
+
-
-
-## Function `is_l1_init_metadata`
+##### Implementation
+public entry fun finalize_arb_hook(
+ module_signer: &signer, arb_index: u64, executor: address
+) acquires ModuleStore, VirtualPool {
+ let module_store = borrow_global_mut<ModuleStore>(@initia_std);
+ assert!(
+ signer::address_of(module_signer)
+ == object::address_from_extend_ref(&module_store.extend_ref),
+ error::permission_denied(EUNAUTHORIZED)
+ );
-fun is_l1_init_metadata(metadata: object::Object<fungible_asset::Metadata>): bool
-
+ let pool_obj =
+ table::remove(
+ &mut module_store.global_arb_batch_map,
+ table_key::encode_u64(arb_index)
+ );
+ let pool = borrow_global_mut<VirtualPool>(object::object_address(&pool_obj));
+ let ArbInfo { executed_time: _, init_used, ibc_op_init_sent, triggering_fee } =
+ table::remove(
+ &mut pool.arb_batch_map,
+ table_key::encode_u64(arb_index)
+ );
+
+ assert!(pool.active, error::invalid_state(EINACTIVE));
+ let pool_signer = object::generate_signer_for_extending(&pool.extend_ref);
+ // update pegkeeper owned balance
+ pool.peg_keeper_owned_ibc_op_init_balance = pool.peg_keeper_owned_ibc_op_init_balance
+ - ibc_op_init_sent;
-
-Implementation
+ // transfer trigger fee
+ primary_fungible_store::transfer(
+ &pool_signer,
+ init_metadata(),
+ executor,
+ triggering_fee
+ );
+ // transfer leftover to module_addr
+ let leftover_amount = ibc_op_init_sent - triggering_fee;
+ primary_fungible_store::transfer(
+ &pool_signer,
+ init_metadata(),
+ signer::address_of(module_signer),
+ leftover_amount
+ );
-fun is_l1_init_metadata(metadata: Object<Metadata>): bool {
- metadata == l1_init_metadata()
+ // update depositor owned init
+ let in_house_arb_profit = leftover_amount - init_used;
+ module_store.depositor_owned_init = module_store.depositor_owned_init
+ + in_house_arb_profit;
+
+ // emit event
+ event::emit(
+ FinalizeArbEvent {
+ arb_index,
+ pool: pool_obj,
+ init_used,
+ ibc_op_init_sent,
+ triggering_fee
+ }
+ );
}
-
+
-
+## Function `create_stableswap_pool`
-## Function `get_d0`
-
-fun get_d0(pool_size: u64, ann: u64): u64
+public entry fun create_stableswap_pool(account: &signer, op_bridge_id: u64, ibc_channel: string::String, ibc_op_init_metadata: object::Object<fungible_asset::Metadata>, init_amount: u64, ibc_op_init_amount: u64)
-
-Implementation
+##### Implementation
+
+
+public entry fun create_stableswap_pool(
+ account: &signer,
+ op_bridge_id: u64,
+ ibc_channel: String,
+ ibc_op_init_metadata: Object<Metadata>,
+ init_amount: u64,
+ ibc_op_init_amount: u64
+) acquires ModuleStore {
+ let module_store = borrow_global_mut<ModuleStore>(@initia_std);
+ let (_, ibc_denom) =
+ check_bridge_info(
+ op_bridge_id,
+ ibc_channel,
+ ibc_op_init_metadata
+ );
+ let creator = object::generate_signer_for_extending(&module_store.extend_ref);
+ let symbol = string::utf8(b"INIT - ");
+ string::append(&mut symbol, ibc_denom);
+
+ let coins: vector<FungibleAsset> = vector[
+ coin::withdraw(
+ account,
+ init_metadata(),
+ init_amount
+ ),
+ coin::withdraw(
+ account,
+ ibc_op_init_metadata,
+ ibc_op_init_amount
+ )
+ ];
+
+ let liquidity_token =
+ stableswap::create_pool(
+ &creator,
+ symbol,
+ symbol,
+ module_store.stableswap_swap_fee_rate,
+ coins,
+ module_store.stableswap_ann
+ );
+ let metadata = fungible_asset::metadata_from_asset(&liquidity_token);
+ let pool = object::convert<Metadata, Pool>(metadata);
+
+ let pools =
+ borrow_pools_with_default(
+ module_store,
+ ibc_op_init_metadata,
+ op_bridge_id,
+ ibc_channel
+ );
+ pools.stableswap_pool = option::some(object::convert<Metadata, Pool>(metadata));
-fun get_d0(pool_size: u64, ann: u64): u64 {
- get_d(pool_size, pool_size, ann)
+ primary_fungible_store::deposit(signer::address_of(account), liquidity_token);
+ event::emit(CreateStableswapPoolEvent { ibc_op_init_metadata, pool });
}
-
-
-
+
-## Function `get_d`
+## Function `provide_internal`
-fun get_d(l1_init_amount: u64, l2_init_amount: u64, ann: u64): u64
+public fun provide_internal(init: fungible_asset::FungibleAsset): fungible_asset::FungibleAsset
-
-Implementation
+##### Implementation
-fun get_d(l1_init_amount: u64, l2_init_amount: u64, ann: u64): u64 {
- let l1_init_amount = (l1_init_amount as u256);
- let l2_init_amount = (l2_init_amount as u256);
- let ann = (ann as u256);
-
- let sum = l1_init_amount + l2_init_amount;
- if (sum == 0) return 0;
- let d = sum;
+public fun provide_internal(init: FungibleAsset): FungibleAsset acquires ModuleStore {
+ // check asset metadata
+ assert!(
+ is_init(&init),
+ error::invalid_argument(ENOT_INIT)
+ );
+ let provide_amount = fungible_asset::amount(&init);
- let i = 0;
+ let module_store = borrow_global_mut<ModuleStore>(@initia_std);
- // converge
- // d = (ann * sum - d_prod) / (ann - 1)
- while (i < 255) {
- let d_prev = d;
- // D ** (n + 1) / (n ** n * prod) in our case, always n = 2
- let d_prod = d * d * d / 4 / l1_init_amount / l2_init_amount;
+ // check emergency
+ assert!(
+ !module_store.emergency_state,
+ error::invalid_state(EEMERGENCY)
+ );
- d = (ann * sum / A_PRECISION + d_prod * 2) * d / ((ann - A_PRECISION) * d / A_PRECISION + 3 * d_prod);
- if (d > d_prev) {
- if (d - d_prev <= 1) break
+ // calculate share amount
+ let total_share = total_share();
+ let share_amount =
+ if (total_share == 0) {
+ provide_amount
} else {
- if (d_prev - d <= 1) break
+ mul_div(
+ provide_amount,
+ (total_share as u64),
+ module_store.depositor_owned_init
+ )
};
- i = i + 1;
- };
- return (d as u64)
+ // update depositor owned init
+ module_store.depositor_owned_init = module_store.depositor_owned_init
+ + provide_amount;
+
+ // deposit token to module
+ let module_addr = object::address_from_extend_ref(&module_store.extend_ref);
+ primary_fungible_store::deposit(module_addr, init);
+
+ // emit event
+ event::emit<ProvideEvent>(ProvideEvent { provide_amount, share_amount });
+
+ // mint share token
+ coin::mint(&module_store.mint_cap, share_amount)
}
-
+
-
+## Function `unbond_internal`
-## Function `get_return_amount`
-
-fun get_return_amount(offer_amount: u64, offer_pool_amount: u64, return_pool_amount: u64, pool_size: u64, ann: u64): u64
+public fun unbond_internal(account: &signer, share_token: fungible_asset::FungibleAsset)
-
-Implementation
+##### Implementation
-fun get_return_amount(offer_amount: u64, offer_pool_amount: u64, return_pool_amount: u64, pool_size: u64, ann: u64): u64 {
- let d = get_d0(pool_size, ann);
- let offer_pool_amount_after = offer_pool_amount + offer_amount;
+public fun unbond_internal(
+ account: &signer, share_token: FungibleAsset
+) acquires ModuleStore {
+ let module_store = borrow_global_mut<ModuleStore>(@initia_std);
- let y = get_y(d, offer_pool_amount_after, ann);
+ // check emergency
+ assert!(
+ !module_store.emergency_state,
+ error::invalid_state(EEMERGENCY)
+ );
- (return_pool_amount - y as u64)
-}
-
+ // check metdata
+ let share_token_metadata = fungible_asset::metadata_from_asset(&share_token);
+ assert!(
+ share_token_metadata == share_token_metadata(),
+ error::invalid_argument(ENOT_SHARE_TOKEN)
+ );
+ // calculate withdraw amount
+ let share_amount = fungible_asset::amount(&share_token);
+ let total_share = total_share();
+ let withdraw_amount =
+ mul_div(
+ share_amount,
+ module_store.depositor_owned_init,
+ total_share
+ );
+ // decrease depositor owned init
+ module_store.depositor_owned_init = module_store.depositor_owned_init
+ - withdraw_amount;
-
+ // burn share token
+ coin::burn(&module_store.burn_cap, share_token);
-
+ // get release time
+ let (_, timestamp) = block::get_block_info();
+ let release_time = timestamp + module_store.unbond_period;
-## Function `get_y`
+ // create and store withdraw entiry
+ let withdraw_entity = UnbondEntity {
+ account: signer::address_of(account),
+ share_amount,
+ withdraw_amount,
+ release_time
+ };
+ let key = generate_unbond_key(signer::address_of(account), release_time);
+ table::add(
+ &mut module_store.unbond_wait_list,
+ key,
+ withdraw_entity
+ );
-get counterparty's amount
+ // emit event
+ event::emit<UnbondEvent>(
+ UnbondEvent {
+ account: signer::address_of(account),
+ share_amount,
+ withdraw_amount,
+ release_time
+ }
+ );
+}
+
-fun get_y(d: u64, x: u64, ann: u64): u64
-
+
+## Function `swap_internal`
-
-Implementation
-fun get_y(d: u64, x: u64, ann: u64): u64 {
- let d = (d as u256);
- let x = (x as u256);
- let ann = (ann as u256);
+public fun swap_internal(offer_asset: fungible_asset::FungibleAsset, return_metadata: object::Object<fungible_asset::Metadata>): fungible_asset::FungibleAsset
+
- // Done by solving quadratic equation iteratively.
- // x_1**2 + x_1 * (sum' - (A*n**n - 1) * D / (A * n**n)) = D ** (n + 1) / (n ** (2 * n) * prod' * A)
- // y**2 + y * (x - (A * 2**2 - 1) * D / (A * 2**2)) = D ** (2 + 1) / (2 ** (2 * 2) * x * A)
- // y**2 + b*y = c
- // y = (y**2 + c) / (2*y + b)
- let c = d * d * d * A_PRECISION / ann / 4 / x; // d ** (2 + 1) / ann / 2 ** 2 / x
- let b_plus_d = x + d * A_PRECISION / ann; // need to sub d but sub later due to value must be less than 0
+##### Implementation
- let y_prev;
- let y = d;
- let i = 0;
- // converge
- while (i < 255) {
- y_prev = y;
- y = (y * y + c) / (2 * y + b_plus_d - d); // sub d here
+public fun swap_internal(
+ offer_asset: FungibleAsset, return_metadata: Object<Metadata>
+): FungibleAsset acquires ModuleStore, VirtualPool {
+ let is_init_offered = is_init(&offer_asset);
+ let offer_metadata = fungible_asset::metadata_from_asset(&offer_asset);
+ let offer_amount = fungible_asset::amount(&offer_asset);
+ let ibc_op_init_metadata = offer_metadata;
+ let (module_store, pool, module_signer, pool_signer) =
+ if (is_init_offered) {
+ ibc_op_init_metadata = return_metadata;
+ borrow_all_mut(return_metadata)
+ } else {
+ borrow_all_mut(offer_metadata)
+ };
+ assert!(pool.active, error::invalid_state(EINACTIVE));
- if (y > y_prev) {
- if (y - y_prev <= 1) break
+ // init offered, do user swap first
+ let (
+ peg_keeper_offer_amount,
+ peg_keeper_return_amount,
+ return_asset,
+ init_swap_fee_amount,
+ init_arb_fee_amount,
+ ibc_op_init_swap_fee_amount,
+ ibc_op_init_arb_fee_amount
+ ) =
+ if (is_init_offered) {
+ // user swap
+ let (
+ return_asset, swap_fee_amount, arb_fee_amount, depositor_return_amount
+ ) =
+ user_swap(
+ offer_asset,
+ return_metadata,
+ module_store,
+ pool,
+ module_signer,
+ pool_signer,
+ is_init_offered
+ );
+
+ // peg keeper swap
+ let (peg_keeper_offer_amount, peg_keeper_return_amount) =
+ peg_keeper_swap(pool);
+
+ // to prevent div by zero
+ let init_arb_fee_amount =
+ if (arb_fee_amount == 0) { 0 }
+ else {
+ mul_div(
+ depositor_return_amount,
+ arb_fee_amount,
+ arb_fee_amount + swap_fee_amount
+ )
+ };
+
+ let init_swap_fee_amount = depositor_return_amount
+ - init_arb_fee_amount;
+
+ (
+ peg_keeper_offer_amount,
+ peg_keeper_return_amount,
+ return_asset,
+ init_swap_fee_amount,
+ init_arb_fee_amount,
+ swap_fee_amount,
+ arb_fee_amount
+ )
+ // if ibc op init offered, do peg keeper swap first
} else {
- if (y_prev - y <= 1) break
+ // peg keeper swap
+ let (peg_keeper_offer_amount, peg_keeper_return_amount) =
+ peg_keeper_swap(pool);
+
+ // user swap
+ let (return_asset, swap_fee_amount, arb_fee_amount, _) =
+ user_swap(
+ offer_asset,
+ return_metadata,
+ module_store,
+ pool,
+ module_signer,
+ pool_signer,
+ is_init_offered
+ );
+
+ (
+ peg_keeper_offer_amount,
+ peg_keeper_return_amount,
+ return_asset,
+ swap_fee_amount,
+ arb_fee_amount,
+ 0,
+ 0
+ )
};
- i = i + 1;
- };
- (y as u64)
+ // check arb
+ check_arb(
+ module_store,
+ pool,
+ ibc_op_init_metadata
+ );
+
+ event::emit<SwapEvent>(
+ SwapEvent {
+ offer_coin: offer_metadata,
+ return_coin: return_metadata,
+ peg_keeper_offer_amount, // always init
+ peg_keeper_return_amount, // always ibc op init
+ offer_amount,
+ return_amount: fungible_asset::amount(&return_asset),
+ init_swap_fee_amount,
+ init_arb_fee_amount,
+ ibc_op_init_swap_fee_amount,
+ ibc_op_init_arb_fee_amount
+ }
+ );
+
+ return_asset
}
-
-
-
+
-## Function `get_fully_recovered_ratio`
+## Function `ibc_ack`
-fun get_fully_recovered_ratio(imbalance: &decimal128::Decimal128, max_ratio: &decimal128::Decimal128, recover_param: &decimal128::Decimal128): decimal128::Decimal128
+public entry fun ibc_ack(pool_signer: &signer, callback_id: u64, success: bool)
-
-Implementation
+##### Implementation
-fun get_fully_recovered_ratio(imbalance: &Decimal128, max_ratio: &Decimal128, recover_param: &Decimal128): Decimal128 {
- let fi = decimal128_safe_mul(recover_param, imbalance);
- let fi3 = decimal128_safe_mul(&fi, &decimal128_safe_mul(&fi, &fi));
- let half = decimal128::from_ratio(1, 2); // .5
- let to_sum = decimal128_safe_mul(
- &decimal128::sub(max_ratio, &half), // R_max - 0.5
- &decimal128_safe_from_ratio(
- decimal128::val(&fi3),
- decimal128::val(&decimal128::add(&decimal128::one(), &fi3)),
- ) // (f * I) ** 3 / (1 + (f * I) ** 3)
+public entry fun ibc_ack(
+ pool_signer: &signer, callback_id: u64, success: bool
+) acquires ModuleStore, VirtualPool {
+ let module_store = borrow_global_mut<ModuleStore>(@initia_std);
+ let pool_obj =
+ table::borrow(
+ &mut module_store.global_arb_batch_map,
+ table_key::encode_u64(callback_id)
+ );
+ let pool = borrow_global_mut<VirtualPool>(object::object_address(&*pool_obj));
+ assert!(
+ signer::address_of(pool_signer)
+ == object::address_from_extend_ref(&pool.extend_ref),
+ error::permission_denied(EUNAUTHORIZED)
);
- decimal128::add(&half, &to_sum)
+ // do nothing
+ if (success) { return };
+
+ revert_arb_state(callback_id);
}
-
+
-
+## Function `ibc_timeout`
-## Function `get_fully_recovered_pool_amounts`
-
-fun get_fully_recovered_pool_amounts(pool_size: u64, fully_recovered_ratio: &decimal128::Decimal128, ann: u64): (u64, u64)
+public entry fun ibc_timeout(pool_signer: &signer, callback_id: u64)
-
-Implementation
-
+##### Implementation
-fun get_fully_recovered_pool_amounts(pool_size: u64, fully_recovered_ratio: &Decimal128, ann: u64): (u64, u64) {
- let denominator = decimal128::val(&decimal128::one());
- let fully_recovered_ratio_val = decimal128::val(fully_recovered_ratio);
- let grad = decimal128::from_ratio(fully_recovered_ratio_val, denominator - fully_recovered_ratio_val);
- let grad_val = decimal128::val(&grad);
- // Increase the value if you want more accurate values, or decrease the value if you want less calculations.
- let sim_size = 100000000u128;
- let sim_size_val = sim_size * denominator;
-
- // Get first point
- let d0 = get_d0((sim_size as u64), ann);
- let x = 2 * sim_size_val / (grad_val + denominator); // x = 2z / (g + 1)
- if (x == sim_size) { // fully_recovered_ratio = 0.5
- return (pool_size, pool_size)
- };
- let y = (get_y(d0, (x as u64), ann) as u128);
-
- let i = 0;
- let x_prev;
- // get the cross point of y = grad * x and [(sim_size, sim_size), (x_prev), (y_prev)]
- // the point is (temp_x, y), get x from y
- while (i < 255) {
- x_prev = x;
- // x = z * (x' - y') / (g * (x'- z) - (y' - z))
- // x = z * (y' - x') / (g * (z - x') + (y' - z))
- let temp_x = sim_size * (y - x) * denominator / (grad_val * (sim_size - x) + (y - sim_size) * denominator);
- let y = decimal128::mul_u128(&grad, temp_x);
- x = (get_y(d0, (y as u64), ann) as u128);
-
- // when fully recovered rate is too close to 0.5 y can be same with sim_size
- if (y == sim_size) break;
-
- // when fully recovered rate is too close to 0.5 x can be slightly higher than sim_size
- if (x > sim_size) {
- x = sim_size;
- break
- };
-
- if (x > x_prev) {
- if (x - x_prev <= 1) break
- } else {
- if (x_prev - x <= 1) break
- };
- i = i + 1;
- };
+public entry fun ibc_timeout(
+ pool_signer: &signer, callback_id: u64
+) acquires ModuleStore, VirtualPool {
+ let module_store = borrow_global_mut<ModuleStore>(@initia_std);
+ let pool_obj =
+ table::borrow(
+ &mut module_store.global_arb_batch_map,
+ table_key::encode_u64(callback_id)
+ );
+ let pool = borrow_global_mut<VirtualPool>(object::object_address(&*pool_obj));
+ assert!(
+ signer::address_of(pool_signer)
+ == object::address_from_extend_ref(&pool.extend_ref),
+ error::permission_denied(EUNAUTHORIZED)
+ );
- // scale up/down to real pool size
- (
- (x * (pool_size as u128) / sim_size as u64),
- (y * (pool_size as u128) / sim_size as u64)
- )
+ revert_arb_state(callback_id);
}
-
+
-
+## Function `safe_swap_simulation`
-## Function `decimal128_safe_mul`
-
-fun decimal128_safe_mul(a: &decimal128::Decimal128, b: &decimal128::Decimal128): decimal128::Decimal128
+public fun safe_swap_simulation(offer_metadata: object::Object<fungible_asset::Metadata>, return_metadata: object::Object<fungible_asset::Metadata>, offer_amount: u64): (u64, u64)
-
-Implementation
-
-
-fun decimal128_safe_mul(a: &Decimal128, b: &Decimal128): Decimal128 {
- let a_val = (decimal128::val(a) as u256);
- let b_val = (decimal128::val(b) as u256);
- let one = (decimal128::val(&decimal128::one()) as u256);
- let val = (a_val * b_val / one as u128);
- decimal128::new(val)
-}
-
-
+##### Implementation
-
+public fun safe_swap_simulation(
+ offer_metadata: Object<Metadata>,
+ return_metadata: Object<Metadata>,
+ offer_amount: u64
+): (u64, u64) acquires ModuleStore, VirtualPool {
+ let is_init_offered = is_init_metadata(offer_metadata);
+ let ibc_op_init_metadata =
+ if (is_init_offered) {
+ return_metadata
+ } else {
+ offer_metadata
+ };
-
+ let virtual_pool_exists = virtual_pool_exists(ibc_op_init_metadata);
-## Function `decimal128_safe_from_ratio`
+ assert!(
+ virtual_pool_exists,
+ error::invalid_argument(EPOOL_NOT_FOUND)
+ );
+ let (init_pool_amount, ibc_op_init_pool_amount) =
+ get_pool_amount(ibc_op_init_metadata, !is_init_offered);
+ let (module_store, pool) = borrow_all(ibc_op_init_metadata);
+ let (pool_size, ann) = (pool.pool_size, pool.ann);
+ let (return_amount, fee_amount) =
+ if (is_init_offered) {
+ let return_amount =
+ get_return_amount(
+ offer_amount,
+ init_pool_amount,
+ ibc_op_init_pool_amount,
+ pool_size,
+ ann
+ );
+
+ if (ibc_op_init_pool_amount - return_amount < pool_size) {
+ return (0, 0)
+ };
+
+ // take swap fee
+ let swap_fee_amount =
+ bigdecimal::mul_by_u64_ceil(
+ module_store.swap_fee_rate,
+ return_amount
+ );
+
+ // take arb fee
+ let arb_profit =
+ if (return_amount > offer_amount + swap_fee_amount) {
+ return_amount - swap_fee_amount - offer_amount
+ } else { 0 };
+ let arb_fee_amount =
+ bigdecimal::mul_by_u64_ceil(
+ module_store.arb_fee_rate,
+ arb_profit
+ );
+ let fee_amount = swap_fee_amount + arb_fee_amount;
+
+ (return_amount, fee_amount)
+ } else {
+ let return_amount =
+ get_return_amount(
+ offer_amount,
+ ibc_op_init_pool_amount,
+ init_pool_amount,
+ pool_size,
+ ann
+ );
+ let fee_amount =
+ bigdecimal::mul_by_u64_ceil(
+ module_store.swap_fee_rate,
+ return_amount
+ );
+
+ (return_amount, fee_amount)
+ };
+ return_amount = return_amount - fee_amount;
-fun decimal128_safe_from_ratio(a: u128, b: u128): decimal128::Decimal128
+ (return_amount, fee_amount)
+}
-
-Implementation
-
-
-fun decimal128_safe_from_ratio(a: u128, b: u128): Decimal128 {
- let a = (a as u256);
- let b = (b as u256);
- let one = (decimal128::val(&decimal128::one()) as u256);
- let val = (a * one / b as u128);
- decimal128::new(val)
-}
-
+
+## Function `safe_swap_simulation_given_out`
-
-
+public fun safe_swap_simulation_given_out(offer_metadata: object::Object<fungible_asset::Metadata>, return_metadata: object::Object<fungible_asset::Metadata>, return_amount: u64): (u64, u64)
+
-## Function `assert_min_amount`
+##### Implementation
-fun assert_min_amount(fa: &fungible_asset::FungibleAsset, min_return: option::Option<u64>)
-
+public fun safe_swap_simulation_given_out(
+ offer_metadata: Object<Metadata>,
+ return_metadata: Object<Metadata>,
+ return_amount: u64
+): (u64, u64) acquires ModuleStore, VirtualPool {
+ let is_init_offered = is_init_metadata(offer_metadata);
+ let ibc_op_init_metadata =
+ if (is_init_offered) {
+ return_metadata
+ } else {
+ offer_metadata
+ };
+ let virtual_pool_exists = virtual_pool_exists(ibc_op_init_metadata);
-
-Implementation
+ assert!(
+ virtual_pool_exists,
+ error::invalid_argument(EPOOL_NOT_FOUND)
+ );
+ let (init_pool_amount, ibc_op_init_pool_amount) =
+ get_pool_amount(ibc_op_init_metadata, !is_init_offered);
+ let (module_store, pool) = borrow_all(ibc_op_init_metadata);
+ let (pool_size, ann) = (pool.pool_size, pool.ann);
+ let (offer_amount, fee_amount) =
+ if (is_init_offered) {
+ // first assume there are no arb fee and calculate offer amount
+ // and then calculate arb fee and get actual return amount which is same with return_amount_before_swap_fee - swap_fee_amount - arb_fee_amount
+ // to make actual return amount to return amount, set return_amount_before_swap_fee = return_amount_before_swap_fee + return_diff
+ // where return_diff = target return amount - actual return amount
+ // and recalculate offer amount repeatly until return amount <= actual return amount
+ // note that actual return is always small or equal with target return amount
+
+ // adjust fee. return amount before swap fee = return amount * 1 / (1 - f)
+ let return_amount_before_swap_fee =
+ bigdecimal::truncate_u64(
+ bigdecimal::div(
+ bigdecimal::from_u64(return_amount),
+ bigdecimal::sub(bigdecimal::one(), module_store.swap_fee_rate)
+ )
+ );
+ if (ibc_op_init_pool_amount - return_amount_before_swap_fee < pool_size) {
+ return ((U64_MAX as u64), (U64_MAX as u64))
+ };
+
+ let swap_fee_amount = return_amount_before_swap_fee - return_amount;
+
+ let offer_amount =
+ get_offer_amount(
+ return_amount_before_swap_fee,
+ init_pool_amount,
+ ibc_op_init_pool_amount,
+ pool_size,
+ ann
+ );
+
+ // calculate arb fee
+ let arb_profit =
+ if (return_amount > offer_amount) {
+ return_amount - offer_amount
+ } else { 0 };
+ let arb_fee_amount =
+ bigdecimal::mul_by_u64_ceil(
+ module_store.arb_fee_rate,
+ arb_profit
+ );
+
+ // actual return amount is return amount - arb fee
+ let actual_return_amount = return_amount - arb_fee_amount;
+ let return_diff = arb_fee_amount;
+
+ // retry while actual return amount is equal to return amount
+ let i = 0;
+ while (return_amount > actual_return_amount && i < 255) {
+ return_amount_before_swap_fee = return_amount_before_swap_fee
+ + return_diff;
+
+ if (ibc_op_init_pool_amount - return_amount_before_swap_fee
+ < pool_size) {
+ return ((U64_MAX as u64), (U64_MAX as u64))
+ };
+
+ swap_fee_amount = bigdecimal::mul_by_u64_ceil(
+ module_store.swap_fee_rate,
+ return_amount_before_swap_fee
+ );
+
+ offer_amount = get_offer_amount(
+ return_amount_before_swap_fee,
+ init_pool_amount,
+ ibc_op_init_pool_amount,
+ pool_size,
+ ann
+ );
+
+ // calculate arb fee
+ arb_profit = if (return_amount > offer_amount) {
+ return_amount_before_swap_fee - swap_fee_amount - offer_amount
+ } else { 0 };
+ arb_fee_amount = bigdecimal::mul_by_u64_ceil(
+ module_store.arb_fee_rate,
+ arb_profit
+ );
+ actual_return_amount = return_amount_before_swap_fee
+ - swap_fee_amount - arb_fee_amount;
+ if (actual_return_amount >= return_amount) break;
+
+ return_diff = return_amount - actual_return_amount;
+ i = i + 1;
+ };
+
+ (offer_amount, swap_fee_amount + arb_fee_amount)
+ } else {
+ // adjust fee. amount = amount * 1 / (1 - f)
+ let return_amount_ =
+ bigdecimal::truncate_u64(
+ bigdecimal::div(
+ bigdecimal::from_u64(return_amount),
+ bigdecimal::sub(bigdecimal::one(), module_store.swap_fee_rate)
+ )
+ );
+ let fee_amount = return_amount_ - return_amount;
+
+ let offer_amount =
+ get_offer_amount(
+ return_amount_,
+ ibc_op_init_pool_amount,
+ init_pool_amount,
+ pool_size,
+ ann
+ );
+
+ (offer_amount, fee_amount)
+ };
-fun assert_min_amount(fa: &FungibleAsset, min_return: Option<u64>) {
- if (option::is_some(&min_return)) {
- let amount = fungible_asset::amount(fa);
- assert!(amount >= option::extract(&mut min_return), error::invalid_state(EMIN_RETURN))
- }
+ (offer_amount, fee_amount)
}
-
-
-
-
diff --git a/initia_stdlib/doc/multisig.md b/initia_stdlib/doc/multisig.md
index 6e11339..0a881a7 100644
--- a/initia_stdlib/doc/multisig.md
+++ b/initia_stdlib/doc/multisig.md
@@ -21,16 +21,10 @@
- [Function `get_config`](#0x1_multisig_get_config)
- [Function `create_multisig_account`](#0x1_multisig_create_multisig_account)
- [Function `create_proposal`](#0x1_multisig_create_proposal)
+- [Function `create_proposal_with_json`](#0x1_multisig_create_proposal_with_json)
- [Function `vote_proposal`](#0x1_multisig_vote_proposal)
- [Function `execute_proposal`](#0x1_multisig_execute_proposal)
- [Function `update_config`](#0x1_multisig_update_config)
-- [Function `is_proposal_expired`](#0x1_multisig_is_proposal_expired)
-- [Function `vote`](#0x1_multisig_vote)
-- [Function `yes_vote_count`](#0x1_multisig_yes_vote_count)
-- [Function `proposal_to_proposal_response`](#0x1_multisig_proposal_to_proposal_response)
-- [Function `assert_member`](#0x1_multisig_assert_member)
-- [Function `assert_config_version`](#0x1_multisig_assert_config_version)
-- [Function `assert_proposal`](#0x1_multisig_assert_proposal)
use 0x1::block;
@@ -53,8 +47,8 @@
## Struct `Period`
Period
represents a time period with optional expiry conditions.
-If both height
and timestamp
are None
, the period is considered to never expire.
-If both height
and timestamp
are set, and only one of them has expired, the period is considered expired.
+If both height
and timestamp
are None
, the period is considered to never expire.
+If both height
and timestamp
are set, and only one of them has expired, the period is considered expired.
struct Period has copy, drop, store
@@ -62,8 +56,7 @@ If both height
and timestamp
are set, and only one of
-
-Fields
+##### Fields
@@ -74,7 +67,7 @@ If both height
and timestamp
are set, and only one of
-
-
timestamp: option::Option<u64>
+timestamp: option::Option<u64>
-
@@ -82,8 +75,6 @@ If both
height
and timestamp
are set, and only one of
-
-
## Resource `MultisigWallet`
@@ -95,8 +86,7 @@ If both height
and timestamp
are set, and only one of
-
-Fields
+##### Fields
@@ -139,8 +129,6 @@ If both height
and timestamp
are set, and only one of
-
-
## Struct `Proposal`
@@ -152,8 +140,7 @@ If both height
and timestamp
are set, and only one of
-
-Fields
+##### Fields
@@ -217,10 +204,20 @@ If both height
and timestamp
are set, and only one of
-
-
+-
+
is_json: bool
+
+-
+
+-
+
json_args: vector<string::String>
+
+-
+
+
+
-
@@ -234,8 +231,7 @@ If both height
and timestamp
are set, and only one of
-
-Fields
+##### Fields
@@ -266,8 +262,6 @@ If both height
and timestamp
are set, and only one of
-
-
## Struct `CreateProposalEvent`
@@ -280,8 +274,7 @@ If both height
and timestamp
are set, and only one of
-
-Fields
+##### Fields
@@ -336,8 +329,6 @@ If both height
and timestamp
are set, and only one of
-
-
## Struct `VoteProposalEvent`
@@ -350,8 +341,7 @@ If both height
and timestamp
are set, and only one of
-
-Fields
+##### Fields
@@ -382,8 +372,6 @@ If both height
and timestamp
are set, and only one of
-
-
## Struct `ExecuteProposalEvent`
@@ -396,8 +384,7 @@ If both height
and timestamp
are set, and only one of
-
-Fields
+##### Fields
@@ -422,8 +409,6 @@ If both height
and timestamp
are set, and only one of
-
-
## Struct `UpdateConfigEvent`
@@ -436,8 +421,7 @@ If both height
and timestamp
are set, and only one of
-
-Fields
+##### Fields
@@ -468,8 +452,6 @@ If both height
and timestamp
are set, and only one of
-
-
## Struct `ProposalResponse`
@@ -481,8 +463,7 @@ If both height
and timestamp
are set, and only one of
-
-Fields
+##### Fields
@@ -558,10 +539,20 @@ If both height
and timestamp
are set, and only one of
-
-
+
+is_json: bool
+
+
+
+
+json_args: vector<string::String>
+
+
+
+
+
-
@@ -574,8 +565,7 @@ If both height
and timestamp
are set, and only one of
-
-Fields
+##### Fields
@@ -612,8 +602,6 @@ If both height
and timestamp
are set, and only one of
-
-
## Constants
@@ -695,7 +683,7 @@ If both height
and timestamp
are set, and only one of
-const EPROPOSAL_NOT_FOUND: u64 = 8;
+const EPROPOSAL_NOT_FOUND: u64 = 9;
@@ -730,21 +718,25 @@ If both height
and timestamp
are set, and only one of
-
-Implementation
+##### Implementation
-public fun get_proposal(multisig_addr: address, proposal_id: u64): ProposalResponse acquires MultisigWallet {
+public fun get_proposal(
+ multisig_addr: address, proposal_id: u64
+): ProposalResponse acquires MultisigWallet {
let multisig_wallet = borrow_global<MultisigWallet>(multisig_addr);
let proposal = table::borrow(&multisig_wallet.proposals, proposal_id);
- proposal_to_proposal_response(multisig_wallet, multisig_addr, proposal_id, proposal)
+ proposal_to_proposal_response(
+ multisig_wallet,
+ multisig_addr,
+ proposal_id,
+ proposal
+ )
}
-
-
## Function `get_proposals`
@@ -757,19 +749,36 @@ If both height
and timestamp
are set, and only one of
-
-Implementation
+##### Implementation
-public fun get_proposals(multisig_addr: address, start_after: Option<u64>, limit: u8): vector<ProposalResponse> acquires MultisigWallet {
- if (limit > MAX_LIMIT) { limit = MAX_LIMIT };
+public fun get_proposals(
+ multisig_addr: address, start_after: Option<u64>, limit: u8
+): vector<ProposalResponse> acquires MultisigWallet {
+ if (limit > MAX_LIMIT) {
+ limit = MAX_LIMIT
+ };
let res: vector<ProposalResponse> = vector[];
let multisig_wallet = borrow_global<MultisigWallet>(multisig_addr);
- let iter = table::iter(&multisig_wallet.proposals, option::none(), start_after, 2);
+ let iter = table::iter(
+ &multisig_wallet.proposals,
+ option::none(),
+ start_after,
+ 2
+ );
- while (vector::length(&res) < (limit as u64) && table::prepare<u64, Proposal>(&mut iter)) {
- let (proposal_id, proposal) = table::next<u64, Proposal>(&mut iter);
- vector::push_back(&mut res, proposal_to_proposal_response(multisig_wallet, multisig_addr, proposal_id, proposal));
+ while (vector::length(&res) < (limit as u64)
+ && table::prepare<u64, Proposal>(iter)) {
+ let (proposal_id, proposal) = table::next<u64, Proposal>(iter);
+ vector::push_back(
+ &mut res,
+ proposal_to_proposal_response(
+ multisig_wallet,
+ multisig_addr,
+ proposal_id,
+ proposal
+ )
+ );
};
res
@@ -778,8 +787,6 @@ If both height
and timestamp
are set, and only one of
-
-
## Function `get_config`
@@ -792,8 +799,7 @@ If both height
and timestamp
are set, and only one of
-
-Implementation
+##### Implementation
public fun get_config(multisig_addr: address): ConfigResponse acquires MultisigWallet {
@@ -804,15 +810,13 @@ If both height
and timestamp
are set, and only one of
config_version: multisig_wallet.config_version,
members: multisig_wallet.members,
threshold: multisig_wallet.threshold,
- max_voting_period: multisig_wallet.max_voting_period,
+ max_voting_period: multisig_wallet.max_voting_period
}
}
-
-
## Function `create_multisig_account`
@@ -825,8 +829,7 @@ Create new multisig account
-
-Implementation
+##### Implementation
public entry fun create_multisig_account(
@@ -835,36 +838,47 @@ Create new multisig account
members: vector<address>,
threshold: u64,
max_voting_period_height: Option<u64>,
- max_voting_period_timestamp: Option<u64>,
+ max_voting_period_timestamp: Option<u64>
) {
assert_member(&members, &signer::address_of(account));
- assert!(vector::length(&members) >= threshold, error::invalid_argument(EINVALID_THRESHOLD));
- let constructor_ref = object::create_named_object(account, *string::bytes(&name), false);
+ assert!(
+ vector::length(&members) >= threshold,
+ error::invalid_argument(EINVALID_THRESHOLD)
+ );
+ let constructor_ref = object::create_named_object(
+ account, *string::bytes(&name)
+ );
let extend_ref = object::generate_extend_ref(&constructor_ref);
let multisig_signer = object::generate_signer(&constructor_ref);
let multisig_addr = signer::address_of(&multisig_signer);
let max_voting_period = Period {
height: max_voting_period_height,
- timestamp: max_voting_period_timestamp,
+ timestamp: max_voting_period_timestamp
};
let members_map = simple_map::create<address, bool>();
- vector::for_each(members, |member| simple_map::add(&mut members_map, member, true)); // just for check uniqueness
-
- move_to(&multisig_signer, MultisigWallet {
- extend_ref,
- config_version: 1,
+ vector::for_each(
members,
- threshold,
- max_voting_period,
- proposals: table::new(),
- });
+ |member| simple_map::add(&mut members_map, member, true)
+ ); // just for check uniqueness
+
+ move_to(
+ &multisig_signer,
+ MultisigWallet {
+ extend_ref,
+ config_version: 1,
+ members,
+ threshold,
+ max_voting_period,
+ proposals: table::new()
+ }
+ );
event::emit<CreateMultisigAccountEvent>(
CreateMultisigAccountEvent {
multisig_addr,
members,
threshold,
- max_voting_period,
+ max_voting_period
}
)
}
@@ -872,8 +886,6 @@ Create new multisig account
-
-
## Function `create_proposal`
@@ -886,8 +898,7 @@ Create new proposal
-
-Implementation
+##### Implementation
public entry fun create_proposal(
@@ -897,50 +908,64 @@ Create new proposal
module_name: String,
function_name: String,
type_args: vector<String>,
- args: vector<vector<u8>>,
+ args: vector<vector<u8>>
) acquires MultisigWallet {
- let addr = signer::address_of(account);
- let multisig_wallet = borrow_global_mut<MultisigWallet>(multisig_addr);
- assert_member(&multisig_wallet.members, &addr);
-
- let (height, timestamp) = get_block_info();
- let config_version = multisig_wallet.config_version;
-
- let proposal = Proposal {
+ create_proposal_internal(
+ account,
+ multisig_addr,
module_address,
module_name,
function_name,
type_args,
args,
- config_version,
- proposal_height: height,
- proposal_timestamp: timestamp,
- votes: simple_map::create(),
- status: 0, // in voting period
- };
+ false,
+ vector[]
+ )
+}
+
- let proposal_id = table::length(&multisig_wallet.proposals) + 1;
- table::add(&mut multisig_wallet.proposals, proposal_id, proposal);
- event::emit<CreateProposalEvent>(
- CreateProposalEvent {
- multisig_addr,
- proposal_id,
- module_address,
- module_name,
- function_name,
- type_args,
- args,
- config_version,
- }
+
+
+
+## Function `create_proposal_with_json`
+
+Create new proposal
+
+
+public entry fun create_proposal_with_json(account: &signer, multisig_addr: address, module_address: address, module_name: string::String, function_name: string::String, type_args: vector<string::String>, args: vector<string::String>)
+
+
+
+
+##### Implementation
+
+
+public entry fun create_proposal_with_json(
+ account: &signer,
+ multisig_addr: address,
+ module_address: address,
+ module_name: String,
+ function_name: String,
+ type_args: vector<String>,
+ args: vector<String>
+) acquires MultisigWallet {
+ create_proposal_internal(
+ account,
+ multisig_addr,
+ module_address,
+ module_name,
+ function_name,
+ type_args,
+ vector[],
+ true,
+ args
)
}
-
-
## Function `vote_proposal`
@@ -953,21 +978,26 @@ Vote proposal
-
-Implementation
+##### Implementation
public entry fun vote_proposal(
account: &signer,
multisig_addr: address,
proposal_id: u64,
- vote_yes: bool,
+ vote_yes: bool
) acquires MultisigWallet {
let voter = signer::address_of(account);
let multisig_wallet = borrow_global_mut<MultisigWallet>(multisig_addr);
assert_member(&multisig_wallet.members, &voter);
- assert!(table::contains(&multisig_wallet.proposals, proposal_id), error::invalid_argument(EPROPOSAL_NOT_FOUND));
+ assert!(
+ table::contains(
+ &multisig_wallet.proposals,
+ proposal_id
+ ),
+ error::invalid_argument(EPROPOSAL_NOT_FOUND)
+ );
let proposal = table::borrow_mut(&mut multisig_wallet.proposals, proposal_id);
assert_config_version(multisig_wallet.config_version, proposal);
@@ -976,20 +1006,13 @@ Vote proposal
vote(&mut proposal.votes, voter, vote_yes);
event::emit<VoteProposalEvent>(
- VoteProposalEvent {
- multisig_addr,
- proposal_id,
- voter,
- vote_yes,
- }
+ VoteProposalEvent { multisig_addr, proposal_id, voter, vote_yes }
)
}
-
-
## Function `execute_proposal`
@@ -1002,20 +1025,23 @@ Execute proposal
-
-Implementation
+##### Implementation
public entry fun execute_proposal(
- account: &signer,
- multisig_addr: address,
- proposal_id: u64,
+ account: &signer, multisig_addr: address, proposal_id: u64
) acquires MultisigWallet {
let executor = signer::address_of(account);
let multisig_wallet = borrow_global_mut<MultisigWallet>(multisig_addr);
assert_member(&multisig_wallet.members, &executor);
- assert!(table::contains(&multisig_wallet.proposals, proposal_id), error::invalid_argument(EPROPOSAL_NOT_FOUND));
+ assert!(
+ table::contains(
+ &multisig_wallet.proposals,
+ proposal_id
+ ),
+ error::invalid_argument(EPROPOSAL_NOT_FOUND)
+ );
let proposal = table::borrow_mut(&mut multisig_wallet.proposals, proposal_id);
assert_config_version(multisig_wallet.config_version, proposal);
@@ -1023,36 +1049,46 @@ Execute proposal
// check passed
assert!(
- yes_vote_count(&proposal.votes, &multisig_wallet.members) >= multisig_wallet.threshold,
- error::invalid_state(ENOT_PASS),
+ yes_vote_count(
+ &proposal.votes,
+ &multisig_wallet.members
+ ) >= multisig_wallet.threshold,
+ error::invalid_state(ENOT_PASS)
);
- let multisig_signer = &object::generate_signer_for_extending(&multisig_wallet.extend_ref);
- move_execute(
- multisig_signer,
- proposal.module_address,
- proposal.module_name,
- proposal.function_name,
- proposal.type_args,
- proposal.args,
- );
+ let multisig_signer =
+ &object::generate_signer_for_extending(&multisig_wallet.extend_ref);
+
+ if (!proposal.is_json) {
+ move_execute(
+ multisig_signer,
+ proposal.module_address,
+ proposal.module_name,
+ proposal.function_name,
+ proposal.type_args,
+ proposal.args
+ )
+ } else {
+ move_execute_with_json(
+ multisig_signer,
+ proposal.module_address,
+ proposal.module_name,
+ proposal.function_name,
+ proposal.type_args,
+ proposal.json_args
+ )
+ };
proposal.status = 1; // executed
event::emit<ExecuteProposalEvent>(
- ExecuteProposalEvent {
- multisig_addr,
- proposal_id,
- executor,
- }
+ ExecuteProposalEvent { multisig_addr, proposal_id, executor }
)
}
-
-
## Function `update_config`
@@ -1065,8 +1101,7 @@ Update config. Only execute by multisig wallet itself
-
-Implementation
+##### Implementation
public entry fun update_config(
@@ -1074,17 +1109,23 @@ Update config. Only execute by multisig wallet itself
new_members: vector<address>,
new_threshold: u64,
new_max_voting_period_height: Option<u64>,
- new_max_voting_period_timestamp: Option<u64>,
+ new_max_voting_period_timestamp: Option<u64>
) acquires MultisigWallet {
let multisig_addr = signer::address_of(account);
let multisig_wallet = borrow_global_mut<MultisigWallet>(multisig_addr);
- assert!(vector::length(&new_members) >= new_threshold, error::invalid_argument(EINVALID_THRESHOLD));
+ assert!(
+ vector::length(&new_members) >= new_threshold,
+ error::invalid_argument(EINVALID_THRESHOLD)
+ );
let new_members_map = simple_map::create<address, bool>();
- vector::for_each(new_members, |member| simple_map::add(&mut new_members_map, member, true)); // just for check uniqueness
+ vector::for_each(
+ new_members,
+ |member| simple_map::add(&mut new_members_map, member, true)
+ ); // just for check uniqueness
let new_max_voting_period = Period {
height: new_max_voting_period_height,
- timestamp: new_max_voting_period_timestamp,
+ timestamp: new_max_voting_period_timestamp
};
multisig_wallet.config_version = multisig_wallet.config_version + 1;
@@ -1097,240 +1138,8 @@ Update config. Only execute by multisig wallet itself
multisig_addr,
members: new_members,
threshold: new_threshold,
- max_voting_period: new_max_voting_period,
+ max_voting_period: new_max_voting_period
}
)
}
-
-
-
-
-
-
-
-## Function `is_proposal_expired`
-
-
-
-fun is_proposal_expired(max_period: &multisig::Period, proposal_height: u64, proposal_timestamp: u64): bool
-
-
-
-
-
-Implementation
-
-
-fun is_proposal_expired(max_period: &Period, proposal_height: u64, proposal_timestamp: u64): bool {
- let (height, timestamp) = get_block_info();
- let expired_height = if (option::is_some(&max_period.height)) {
- let max_voting_period_height = *option::borrow(&max_period.height);
- (max_voting_period_height + proposal_height) >= height
- } else {
- false
- };
-
- let expired_timestamp = if (option::is_some(&max_period.timestamp)) {
- let max_voting_period_timestamp = *option::borrow(&max_period.timestamp);
- (max_voting_period_timestamp + proposal_timestamp) >= timestamp
- } else {
- false
- };
-
- expired_height || expired_timestamp
-}
-
-
-
-
-
-
-
-
-## Function `vote`
-
-
-
-fun vote(votes: &mut simple_map::SimpleMap<address, bool>, voter: address, vote_yes: bool)
-
-
-
-
-
-Implementation
-
-
-fun vote(votes: &mut SimpleMap<address, bool>, voter: address, vote_yes: bool) {
- if (simple_map::contains_key(votes, &voter)) {
- let vote = simple_map::borrow_mut(votes, &voter);
- *vote = vote_yes;
- } else {
- simple_map::add(votes, voter, vote_yes);
- };
-}
-
-
-
-
-
-
-
-
-## Function `yes_vote_count`
-
-
-
-fun yes_vote_count(votes: &simple_map::SimpleMap<address, bool>, members: &vector<address>): u64
-
-
-
-
-
-Implementation
-
-
-fun yes_vote_count(votes: &SimpleMap<address, bool>, members: &vector<address>): u64 {
- let yes_count = 0;
- vector::for_each_ref(members, |member| {
- if (simple_map::contains_key(votes, member) && *simple_map::borrow(votes, member)) {
- yes_count = yes_count + 1;
- }
- });
-
- yes_count
-}
-
-
-
-
-
-
-
-
-## Function `proposal_to_proposal_response`
-
-
-
-fun proposal_to_proposal_response(multisig_wallet: &multisig::MultisigWallet, multisig_addr: address, proposal_id: u64, proposal: &multisig::Proposal): multisig::ProposalResponse
-
-
-
-
-
-Implementation
-
-
-fun proposal_to_proposal_response(
- multisig_wallet: &MultisigWallet,
- multisig_addr: address,
- proposal_id: u64,
- proposal: &Proposal,
-): ProposalResponse {
- let status_index = proposal.status;
- let is_expired = is_proposal_expired(&multisig_wallet.max_voting_period, proposal.proposal_height, proposal.proposal_timestamp);
- let yes_vote_count = yes_vote_count(&proposal.votes, &multisig_wallet.members);
- if (status_index == 0 && is_expired) {
- status_index = 2
- };
-
- ProposalResponse {
- multisig_addr,
- proposal_id,
- module_address: proposal.module_address,
- module_name: proposal.module_name,
- function_name: proposal.function_name,
- type_args: proposal.type_args,
- args: proposal.args,
- proposal_height: proposal.proposal_height,
- proposal_timestamp: proposal.proposal_timestamp,
- config_version: proposal.config_version,
- yes_vote_count,
- status: string::utf8(*vector::borrow(&STATUS, (status_index as u64))),
- }
-}
-
-
-
-
-
-
-
-
-## Function `assert_member`
-
-
-
-fun assert_member(members: &vector<address>, member: &address)
-
-
-
-
-
-Implementation
-
-
-inline fun assert_member(members: &vector<address>, member: &address) {
- assert!(vector::contains(members, member), error::permission_denied(ENOT_MEMBER))
-}
-
-
-
-
-
-
-
-
-## Function `assert_config_version`
-
-
-
-fun assert_config_version(multisig_wallet_config_version: u64, execute_proposal: &multisig::Proposal)
-
-
-
-
-
-Implementation
-
-
-inline fun assert_config_version(multisig_wallet_config_version: u64, execute_proposal: &Proposal) {
- assert!(multisig_wallet_config_version == execute_proposal.config_version, error::invalid_state(EOLD_CONFIG_VERSION))
-}
-
-
-
-
-
-
-
-
-## Function `assert_proposal`
-
-
-
-fun assert_proposal(max_voting_period: &multisig::Period, proposal: &multisig::Proposal)
-
-
-
-
-
-Implementation
-
-
-inline fun assert_proposal(max_voting_period: &Period, proposal: &Proposal) {
- assert!(proposal.status == 0, error::invalid_state(EINVALID_PROPOSAL_STATUS));
- assert!(
- !is_proposal_expired(
- max_voting_period,
- proposal.proposal_height,
- proposal.proposal_timestamp,
- ),
- error::invalid_state(EPROPOSAL_EXPIRED),
- );
-}
-
-
-
-
-
diff --git a/initia_stdlib/doc/nft.md b/initia_stdlib/doc/nft.md
index d64051e..0216b6b 100644
--- a/initia_stdlib/doc/nft.md
+++ b/initia_stdlib/doc/nft.md
@@ -16,14 +16,12 @@ nft are:
- [Struct `MutationEvent`](#0x1_nft_MutationEvent)
- [Struct `NftInfoResponse`](#0x1_nft_NftInfoResponse)
- [Constants](#@Constants_0)
-- [Function `create_common`](#0x1_nft_create_common)
- [Function `create`](#0x1_nft_create)
- [Function `create_nft_address`](#0x1_nft_create_nft_address)
- [Function `create_nft_seed`](#0x1_nft_create_nft_seed)
- [Function `generate_mutator_ref`](#0x1_nft_generate_mutator_ref)
- [Function `generate_burn_ref`](#0x1_nft_generate_burn_ref)
- [Function `address_from_burn_ref`](#0x1_nft_address_from_burn_ref)
-- [Function `borrow`](#0x1_nft_borrow)
- [Function `is_nft`](#0x1_nft_is_nft)
- [Function `creator`](#0x1_nft_creator)
- [Function `collection_name`](#0x1_nft_collection_name)
@@ -34,7 +32,6 @@ nft are:
- [Function `royalty`](#0x1_nft_royalty)
- [Function `nft_info`](#0x1_nft_nft_info)
- [Function `nft_infos`](#0x1_nft_nft_infos)
-- [Function `borrow_mut`](#0x1_nft_borrow_mut)
- [Function `burn`](#0x1_nft_burn)
- [Function `set_description`](#0x1_nft_set_description)
- [Function `set_uri`](#0x1_nft_set_uri)
@@ -65,8 +62,7 @@ Represents the common fields to all nfts.
-
-Fields
+##### Fields
@@ -99,8 +95,6 @@ Represents the common fields to all nfts.
-
-
## Struct `BurnRef`
@@ -115,8 +109,7 @@ a small optimization to support either and take a fixed amount of 34-bytes.
-
-Fields
+##### Fields
@@ -129,8 +122,6 @@ a small optimization to support either and take a fixed amount of 34-bytes.
-
-
## Struct `MutatorRef`
@@ -143,8 +134,7 @@ This enables mutating descritpion and URI by higher level services.
-
-Fields
+##### Fields
@@ -157,8 +147,6 @@ This enables mutating descritpion and URI by higher level services.
-
-
## Struct `MutationEvent`
@@ -173,8 +161,7 @@ directly understand the behavior in a writeset.
-
-Fields
+##### Fields
@@ -205,8 +192,6 @@ directly understand the behavior in a writeset.
-
-
## Struct `NftInfoResponse`
@@ -219,8 +204,7 @@ Struct for nft info query response
-
-Fields
+##### Fields
@@ -251,8 +235,6 @@ Struct for nft info query response
-
-
## Constants
@@ -306,6 +288,16 @@ The field being changed is not mutable
+
+
+The provided token id is invalid
+
+
+const EINVALID_TOKEN_ID: u64 = 9;
+
+
+
+
The nft does not exist
@@ -364,58 +356,6 @@ The query length is over the maximum length
-
-
-## Function `create_common`
-
-
-
-fun create_common(constructor_ref: &object::ConstructorRef, creator_address: address, collection_name: string::String, description: string::String, token_id: string::String, royalty: option::Option<royalty::Royalty>, uri: string::String)
-
-
-
-
-
-Implementation
-
-
-inline fun create_common(
- constructor_ref: &ConstructorRef,
- creator_address: address,
- collection_name: String,
- description: String,
- token_id: String,
- royalty: Option<Royalty>,
- uri: String,
-) {
- assert!(string::length(&token_id) <= MAX_NFT_TOKEN_ID_LENGTH, error::out_of_range(ENFT_TOKEN_ID_TOO_LONG));
- assert!(string::length(&description) <= MAX_DESCRIPTION_LENGTH, error::out_of_range(EDESCRIPTION_TOO_LONG));
- assert!(string::length(&uri) <= MAX_URI_LENGTH, error::out_of_range(EURI_TOO_LONG));
-
- let object_signer = object::generate_signer(constructor_ref);
-
- let collection_addr = collection::create_collection_address(creator_address, &collection_name);
- let collection = object::address_to_object<Collection>(collection_addr);
- collection::increment_supply(collection, token_id, signer::address_of(&object_signer));
-
- let nft = Nft {
- collection,
- description,
- token_id,
- uri,
- };
- move_to(&object_signer, nft);
-
- if (option::is_some(&royalty)) {
- royalty::init(constructor_ref, option::extract(&mut royalty))
- };
-}
-
-
-
-
-
-
## Function `create`
@@ -429,8 +369,7 @@ additional specialization.
-
-Implementation
+##### Implementation
public fun create(
@@ -439,21 +378,27 @@ additional specialization.
description: String,
token_id: String,
royalty: Option<Royalty>,
- uri: String,
+ uri: String
): ConstructorRef {
let creator_address = signer::address_of(creator);
let seed = create_nft_seed(&collection_name, &token_id);
- let constructor_ref = object::create_named_object(creator, seed, true);
- create_common(&constructor_ref, creator_address, collection_name, description, token_id, royalty, uri);
+ let constructor_ref = object::create_deletable_named_object(creator, seed);
+ create_common(
+ &constructor_ref,
+ creator_address,
+ collection_name,
+ description,
+ token_id,
+ royalty,
+ uri
+ );
constructor_ref
}
-
-
## Function `create_nft_address`
@@ -466,19 +411,21 @@ Generates the nft's address based upon the creator's address, the collection's n
-
-Implementation
+##### Implementation
-public fun create_nft_address(creator: address, collection: &String, token_id: &String): address {
- object::create_object_address(creator, create_nft_seed(collection, token_id))
+public fun create_nft_address(
+ creator: address, collection: &String, token_id: &String
+): address {
+ object::create_object_address(
+ &creator,
+ create_nft_seed(collection, token_id)
+ )
}
-
-
## Function `create_nft_seed`
@@ -491,12 +438,14 @@ Named objects are derived from a seed, the nft's seed is its token_id appended t
-
-Implementation
+##### Implementation
public fun create_nft_seed(collection: &String, token_id: &String): vector<u8> {
- assert!(string::length(token_id) <= MAX_NFT_TOKEN_ID_LENGTH, error::out_of_range(ENFT_TOKEN_ID_TOO_LONG));
+ assert!(
+ string::length(token_id) <= MAX_NFT_TOKEN_ID_LENGTH,
+ error::out_of_range(ENFT_TOKEN_ID_TOO_LONG)
+ );
let seed = *string::bytes(collection);
vector::append(&mut seed, b"::");
vector::append(&mut seed, *string::bytes(token_id));
@@ -506,8 +455,6 @@ Named objects are derived from a seed, the nft's seed is its token_id appended t
-
-
## Function `generate_mutator_ref`
@@ -520,20 +467,17 @@ Creates a MutatorRef, which gates the ability to mutate any fields that support
-
-Implementation
+##### Implementation
public fun generate_mutator_ref(ref: &ConstructorRef): MutatorRef {
let object = object::object_from_constructor_ref<Nft>(ref);
- MutatorRef { self: object::object_address(object) }
+ MutatorRef { self: object::object_address(&object) }
}
-
-
## Function `generate_burn_ref`
@@ -546,8 +490,7 @@ Creates a BurnRef, which gates the ability to burn the given nft.
-
-Implementation
+##### Implementation
public fun generate_burn_ref(ref: &ConstructorRef): BurnRef {
@@ -558,8 +501,6 @@ Creates a BurnRef, which gates the ability to burn the given nft.
-
-
## Function `address_from_burn_ref`
@@ -572,8 +513,7 @@ Extracts the nfts address from a BurnRef.
-
-Implementation
+##### Implementation
public fun address_from_burn_ref(ref: &BurnRef): address {
@@ -583,37 +523,6 @@ Extracts the nfts address from a BurnRef.
-
-
-
-
-## Function `borrow`
-
-
-
-fun borrow<T: key>(nft: object::Object<T>): &nft::Nft
-
-
-
-
-
-Implementation
-
-
-inline fun borrow<T: key>(nft: Object<T>): &Nft acquires Nft {
- let nft_address = object::object_address(nft);
- assert!(
- exists<Nft>(nft_address),
- error::not_found(ENFT_DOES_NOT_EXIST),
- );
- borrow_global<Nft>(nft_address)
-}
-
-
-
-
-
-
## Function `is_nft`
@@ -626,8 +535,7 @@ Extracts the nfts address from a BurnRef.
-
-Implementation
+##### Implementation
public fun is_nft(object_address: address): bool {
@@ -637,8 +545,6 @@ Extracts the nfts address from a BurnRef.
-
-
## Function `creator`
@@ -651,8 +557,7 @@ Extracts the nfts address from a BurnRef.
-
-Implementation
+##### Implementation
public fun creator<T: key>(nft: Object<T>): address acquires Nft {
@@ -662,8 +567,6 @@ Extracts the nfts address from a BurnRef.
-
-
## Function `collection_name`
@@ -676,8 +579,7 @@ Extracts the nfts address from a BurnRef.
-
-Implementation
+##### Implementation
public fun collection_name<T: key>(nft: Object<T>): String acquires Nft {
@@ -687,8 +589,6 @@ Extracts the nfts address from a BurnRef.
-
-
## Function `collection_object`
@@ -701,8 +601,7 @@ Extracts the nfts address from a BurnRef.
-
-Implementation
+##### Implementation
public fun collection_object<T: key>(nft: Object<T>): Object<Collection> acquires Nft {
@@ -712,8 +611,6 @@ Extracts the nfts address from a BurnRef.
-
-
## Function `description`
@@ -726,8 +623,7 @@ Extracts the nfts address from a BurnRef.
-
-Implementation
+##### Implementation
public fun description<T: key>(nft: Object<T>): String acquires Nft {
@@ -737,8 +633,6 @@ Extracts the nfts address from a BurnRef.
-
-
## Function `token_id`
@@ -751,8 +645,7 @@ Extracts the nfts address from a BurnRef.
-
-Implementation
+##### Implementation
public fun token_id<T: key>(nft: Object<T>): String acquires Nft {
@@ -762,8 +655,6 @@ Extracts the nfts address from a BurnRef.
-
-
## Function `uri`
@@ -776,8 +667,7 @@ Extracts the nfts address from a BurnRef.
-
-Implementation
+##### Implementation
public fun uri<T: key>(nft: Object<T>): String acquires Nft {
@@ -787,8 +677,6 @@ Extracts the nfts address from a BurnRef.
-
-
## Function `royalty`
@@ -801,8 +689,7 @@ Extracts the nfts address from a BurnRef.
-
-Implementation
+##### Implementation
public fun royalty<T: key>(nft: Object<T>): Option<Royalty> acquires Nft {
@@ -813,8 +700,10 @@ Extracts the nfts address from a BurnRef.
} else {
let creator = creator(nft);
let collection_name = collection_name(nft);
- let collection_address = collection::create_collection_address(creator, &collection_name);
- let collection = object::address_to_object<collection::Collection>(collection_address);
+ let collection_address =
+ collection::create_collection_address(creator, &collection_name);
+ let collection =
+ object::address_to_object<collection::Collection>(collection_address);
royalty::get(collection)
}
}
@@ -822,8 +711,6 @@ Extracts the nfts address from a BurnRef.
-
-
## Function `nft_info`
@@ -836,8 +723,7 @@ Extracts the nfts address from a BurnRef.
-
-Implementation
+##### Implementation
public fun nft_info(nft: Object<Nft>): NftInfoResponse acquires Nft {
@@ -846,15 +732,13 @@ Extracts the nfts address from a BurnRef.
collection: nft.collection,
description: nft.description,
token_id: nft.token_id,
- uri: nft.uri,
+ uri: nft.uri
}
}
-
-
## Function `nft_infos`
@@ -867,13 +751,15 @@ Extracts the nfts address from a BurnRef.
-
-Implementation
+##### Implementation
public fun nft_infos(nfts: vector<Object<Nft>>): vector<NftInfoResponse> acquires Nft {
let len = vector::length(&nfts);
- assert!(len <= MAX_QUERY_LENGTH, error::invalid_argument(EQUERY_LENGTH_TOO_LONG));
+ assert!(
+ len <= MAX_QUERY_LENGTH,
+ error::invalid_argument(EQUERY_LENGTH_TOO_LONG)
+ );
let index = 0;
let res: vector<NftInfoResponse> = vector[];
while (index < len) {
@@ -888,36 +774,6 @@ Extracts the nfts address from a BurnRef.
-
-
-
-
-## Function `borrow_mut`
-
-
-
-fun borrow_mut(mutator_ref: &nft::MutatorRef): &mut nft::Nft
-
-
-
-
-
-Implementation
-
-
-inline fun borrow_mut(mutator_ref: &MutatorRef): &mut Nft acquires Nft {
- assert!(
- exists<Nft>(mutator_ref.self),
- error::not_found(ENFT_DOES_NOT_EXIST),
- );
- borrow_global_mut<Nft>(mutator_ref.self)
-}
-
-
-
-
-
-
## Function `burn`
@@ -929,8 +785,7 @@ Extracts the nfts address from a BurnRef.
-
-Implementation
+##### Implementation
public fun burn(burn_ref: BurnRef) acquires Nft {
@@ -942,12 +797,7 @@ Extracts the nfts address from a BurnRef.
royalty::delete(addr)
};
- let Nft {
- collection,
- description: _,
- token_id,
- uri: _,
- } = move_from<Nft>(addr);
+ let Nft { collection, description: _, token_id, uri: _ } = move_from<Nft>(addr);
collection::decrement_supply(collection, token_id, addr);
}
@@ -955,8 +805,6 @@ Extracts the nfts address from a BurnRef.
-
-
## Function `set_description`
@@ -968,12 +816,16 @@ Extracts the nfts address from a BurnRef.
-
-Implementation
+##### Implementation
-public fun set_description(mutator_ref: &MutatorRef, description: String) acquires Nft {
- assert!(string::length(&description) <= MAX_DESCRIPTION_LENGTH, error::out_of_range(EDESCRIPTION_TOO_LONG));
+public fun set_description(
+ mutator_ref: &MutatorRef, description: String
+) acquires Nft {
+ assert!(
+ string::length(&description) <= MAX_DESCRIPTION_LENGTH,
+ error::out_of_range(EDESCRIPTION_TOO_LONG)
+ );
let nft = borrow_mut(mutator_ref);
event::emit(
MutationEvent {
@@ -981,7 +833,7 @@ Extracts the nfts address from a BurnRef.
mutated_field_name: string::utf8(b"description"),
old_value: nft.description,
new_value: description
- },
+ }
);
nft.description = description;
}
@@ -989,8 +841,6 @@ Extracts the nfts address from a BurnRef.
-
-
## Function `set_uri`
@@ -1002,25 +852,23 @@ Extracts the nfts address from a BurnRef.
-
-Implementation
+##### Implementation
public fun set_uri(mutator_ref: &MutatorRef, uri: String) acquires Nft {
- assert!(string::length(&uri) <= MAX_URI_LENGTH, error::out_of_range(EURI_TOO_LONG));
+ assert!(
+ string::length(&uri) <= MAX_URI_LENGTH,
+ error::out_of_range(EURI_TOO_LONG)
+ );
let nft = borrow_mut(mutator_ref);
event::emit(
MutationEvent {
nft: mutator_ref.self,
mutated_field_name: string::utf8(b"uri"),
old_value: nft.uri,
- new_value: uri,
- },
+ new_value: uri
+ }
);
nft.uri = uri;
}
-
-
-
-
diff --git a/initia_stdlib/doc/object.md b/initia_stdlib/doc/object.md
index c5598a5..94710a9 100644
--- a/initia_stdlib/doc/object.md
+++ b/initia_stdlib/doc/object.md
@@ -35,16 +35,16 @@ make it so that a reference to a global object can be returned from a function.
- [Constants](#@Constants_0)
- [Function `address_to_object`](#0x1_object_address_to_object)
- [Function `is_object`](#0x1_object_is_object)
+- [Function `object_exists`](#0x1_object_object_exists)
- [Function `create_object_address`](#0x1_object_create_object_address)
- [Function `create_user_derived_object_address`](#0x1_object_create_user_derived_object_address)
- [Function `create_guid_object_address`](#0x1_object_create_guid_object_address)
-- [Function `exists_at`](#0x1_object_exists_at)
- [Function `object_address`](#0x1_object_object_address)
- [Function `convert`](#0x1_object_convert)
- [Function `create_named_object`](#0x1_object_create_named_object)
+- [Function `create_deletable_named_object`](#0x1_object_create_deletable_named_object)
- [Function `create_user_derived_object`](#0x1_object_create_user_derived_object)
- [Function `create_object`](#0x1_object_create_object)
-- [Function `create_object_internal`](#0x1_object_create_object_internal)
- [Function `generate_delete_ref`](#0x1_object_generate_delete_ref)
- [Function `generate_extend_ref`](#0x1_object_generate_extend_ref)
- [Function `generate_transfer_ref`](#0x1_object_generate_transfer_ref)
@@ -66,7 +66,6 @@ make it so that a reference to a global object can be returned from a function.
- [Function `transfer`](#0x1_object_transfer)
- [Function `transfer_raw`](#0x1_object_transfer_raw)
- [Function `transfer_to_object`](#0x1_object_transfer_to_object)
-- [Function `verify_ungated_and_descendant`](#0x1_object_verify_ungated_and_descendant)
- [Function `ungated_transfer_allowed`](#0x1_object_ungated_transfer_allowed)
- [Function `owner`](#0x1_object_owner)
- [Function `is_owner`](#0x1_object_is_owner)
@@ -99,8 +98,7 @@ Tombstone is version store for deleted objects with version
-
-Fields
+##### Fields
@@ -113,8 +111,6 @@ Tombstone is version store for deleted objects with version
-
-
## Resource `ObjectCore`
@@ -127,8 +123,7 @@ The core of the object model that defines ownership, transferability, and events
-
-Fields
+##### Fields
@@ -154,8 +149,6 @@ The core of the object model that defines ownership, transferability, and events
-
-
## Struct `Object`
@@ -171,8 +164,7 @@ can remove it from storage at any point in time.
-
-Fields
+##### Fields
@@ -185,8 +177,6 @@ can remove it from storage at any point in time.
-
-
## Struct `ConstructorRef`
@@ -199,8 +189,7 @@ This is a one time ability given to the creator to configure the object as neces
-
-Fields
+##### Fields
@@ -214,7 +203,7 @@ This is a one time ability given to the creator to configure the object as neces
can_delete: bool
-
- True if the object can be deleted. Named objects are not deletable.
+ True if the object can be deleted.
-
version: u64
@@ -225,8 +214,6 @@ This is a one time ability given to the creator to configure the object as neces
-
-
## Struct `DeleteRef`
@@ -239,8 +226,7 @@ Used to remove an object from storage.
-
-Fields
+##### Fields
@@ -259,8 +245,6 @@ Used to remove an object from storage.
-
-
## Struct `ExtendRef`
@@ -273,8 +257,7 @@ Used to create events or move additional resources into object storage.
-
-Fields
+##### Fields
@@ -293,8 +276,6 @@ Used to create events or move additional resources into object storage.
-
-
## Struct `TransferRef`
@@ -307,8 +288,7 @@ Used to create LinearTransferRef, hence ownership transfer.
-
-Fields
+##### Fields
@@ -327,8 +307,6 @@ Used to create LinearTransferRef, hence ownership transfer.
-
-
## Struct `LinearTransferRef`
@@ -342,8 +320,7 @@ the current owner.
-
-Fields
+##### Fields
@@ -368,8 +345,6 @@ the current owner.
-
-
## Struct `DeriveRef`
@@ -382,8 +357,7 @@ Used to create derived objects from a given objects.
-
-Fields
+##### Fields
@@ -402,8 +376,6 @@ Used to create derived objects from a given objects.
-
-
## Struct `CreateEvent`
@@ -417,8 +389,7 @@ Emitted at the object creation.
-
-Fields
+##### Fields
@@ -443,8 +414,6 @@ Emitted at the object creation.
-
-
## Struct `TransferEvent`
@@ -458,8 +427,7 @@ Emitted whenever the object's owner field is changed.
-
-Fields
+##### Fields
@@ -484,8 +452,6 @@ Emitted whenever the object's owner field is changed.
-
-
## Constants
@@ -653,21 +619,24 @@ Produces an ObjectId from the given address. This is not verified.
-
-Implementation
+##### Implementation
public fun address_to_object<T: key>(object: address): Object<T> {
- assert!(exists<ObjectCore>(object), error::not_found(EOBJECT_DOES_NOT_EXIST));
- assert!(exists_at<T>(object), error::not_found(ERESOURCE_DOES_NOT_EXIST));
+ assert!(
+ exists<ObjectCore>(object),
+ error::not_found(EOBJECT_DOES_NOT_EXIST)
+ );
+ assert!(
+ exists_at<T>(object),
+ error::not_found(ERESOURCE_DOES_NOT_EXIST)
+ );
Object<T> { inner: object }
}
-
-
## Function `is_object`
@@ -680,8 +649,7 @@ Returns true if there exists an object or the remnants of an object.
-
-Implementation
+##### Implementation
public fun is_object(object: address): bool {
@@ -691,7 +659,27 @@ Returns true if there exists an object or the remnants of an object.
-
+
+
+## Function `object_exists`
+
+Returns true if there exists an object with resource T.
+
+
+public fun object_exists<T: key>(object: address): bool
+
+
+
+
+##### Implementation
+
+
+public fun object_exists<T: key>(object: address): bool {
+ exists<ObjectCore>(object) && exists_at<T>(object)
+}
+
+
+
@@ -700,17 +688,16 @@ Returns true if there exists an object or the remnants of an object.
Derives an object address from source material: sha3_256([creator address | seed | 0xFE]).
-public fun create_object_address(source: address, seed: vector<u8>): address
+public fun create_object_address(source: &address, seed: vector<u8>): address
-
-Implementation
+##### Implementation
-public fun create_object_address(source: address, seed: vector<u8>): address {
- let bytes = bcs::to_bytes(&source);
+public fun create_object_address(source: &address, seed: vector<u8>): address {
+ let bytes = bcs::to_bytes(source);
vector::append(&mut bytes, seed);
vector::push_back(&mut bytes, OBJECT_FROM_SEED_ADDRESS_SCHEME);
from_bcs::to_address(hash::sha3_256(bytes))
@@ -719,8 +706,6 @@ Derives an object address from source material: sha3_256([creator address | seed
-
-
## Function `create_user_derived_object_address`
@@ -733,11 +718,12 @@ Derives an object address from the source address and an object: sha3_256([sourc
-
-Implementation
+##### Implementation
-public fun create_user_derived_object_address(source: address, derive_from: address): address {
+public fun create_user_derived_object_address(
+ source: address, derive_from: address
+): address {
let bytes = bcs::to_bytes(&source);
vector::append(&mut bytes, bcs::to_bytes(&derive_from));
vector::push_back(&mut bytes, OBJECT_DERIVED_SCHEME);
@@ -747,8 +733,6 @@ Derives an object address from the source address and an object: sha3_256([sourc
-
-
## Function `create_guid_object_address`
@@ -761,11 +745,12 @@ Derives an object from an Account GUID.
-
-Implementation
+##### Implementation
-public fun create_guid_object_address(source: address, creation_num: u64): address {
+public fun create_guid_object_address(
+ source: address, creation_num: u64
+): address {
let id = guid::create_id(source, creation_num);
let bytes = bcs::to_bytes(&id);
vector::push_back(&mut bytes, OBJECT_FROM_GUID_ADDRESS_SCHEME);
@@ -775,30 +760,6 @@ Derives an object from an Account GUID.
-
-
-
-
-## Function `exists_at`
-
-
-
-fun exists_at<T: key>(object: address): bool
-
-
-
-
-
-Implementation
-
-
-native fun exists_at<T: key>(object: address): bool;
-
-
-
-
-
-
## Function `object_address`
@@ -806,24 +767,21 @@ Derives an object from an Account GUID.
Returns the address of within an ObjectId.
-public fun object_address<T: key>(object: object::Object<T>): address
+public fun object_address<T: key>(object: &object::Object<T>): address
-
-Implementation
+##### Implementation
-public fun object_address<T: key>(object: Object<T>): address {
+public fun object_address<T: key>(object: &Object<T>): address {
object.inner
}
-
-
## Function `convert`
@@ -836,8 +794,7 @@ Convert Object to Object.
-
-Implementation
+##### Implementation
public fun convert<X: key, Y: key>(object: Object<X>): Object<Y> {
@@ -847,147 +804,121 @@ Convert Object to Object.
-
-
## Function `create_named_object`
-Create a new named object and return the ConstructorRef. Named objects can be queried globally
-by knowing the user generated seed used to create them. Named objects cannot be deleted.
+Create a new named object and return the ConstructorRef.
+Named objects can be queried globally by knowing the user generated seed used to create them.
-public fun create_named_object(creator: &signer, seed: vector<u8>, can_delete: bool): object::ConstructorRef
+public fun create_named_object(creator: &signer, seed: vector<u8>): object::ConstructorRef
-
-Implementation
+##### Implementation
-public fun create_named_object(creator: &signer, seed: vector<u8>, can_delete: bool): ConstructorRef acquires Tombstone {
+public fun create_named_object(
+ creator: &signer, seed: vector<u8>
+): ConstructorRef acquires Tombstone {
let creator_address = signer::address_of(creator);
- let obj_addr = create_object_address(creator_address, seed);
- create_object_internal(creator_address, obj_addr, can_delete)
+ let obj_addr = create_object_address(&creator_address, seed);
+ create_object_internal(creator_address, obj_addr, false)
}
-
+
-
-
-## Function `create_user_derived_object`
+## Function `create_deletable_named_object`
-Create a new object whose address is derived based on the creator account address and another object.
-Derivde objects, similar to named objects, cannot be deleted.
+Create a new object that can be deleted and return the ConstructorRef.
+Named objects can be queried globally by knowing the user generated seed used to create them.
-public(friend) fun create_user_derived_object(creator_address: address, derive_ref: &object::DeriveRef, can_delete: bool): object::ConstructorRef
+public fun create_deletable_named_object(creator: &signer, seed: vector<u8>): object::ConstructorRef
-
-Implementation
+##### Implementation
-public(friend) fun create_user_derived_object(creator_address: address, derive_ref: &DeriveRef, can_delete: bool): ConstructorRef acquires Tombstone {
- let obj_addr = create_user_derived_object_address(creator_address, derive_ref.self);
- create_object_internal(creator_address, obj_addr, can_delete)
+public fun create_deletable_named_object(
+ creator: &signer, seed: vector<u8>
+): ConstructorRef acquires Tombstone {
+ let creator_address = signer::address_of(creator);
+ let obj_addr = create_object_address(&creator_address, seed);
+ create_object_internal(creator_address, obj_addr, true)
}
-
-
-
+
-## Function `create_object`
+## Function `create_user_derived_object`
-Create a new object by generating a random unique address based on transaction hash.
-The unique address is computed sha3_256([transaction hash | auid counter | 0xFB]).
+Create a new object whose address is derived based on the creator account address and another object.
+Derivde objects, similar to named objects, cannot be deleted.
-public fun create_object(owner_address: address, can_delete: bool): object::ConstructorRef
+public(friend) fun create_user_derived_object(creator_address: address, derive_ref: &object::DeriveRef, can_delete: bool): object::ConstructorRef
-
-Implementation
+##### Implementation
-public fun create_object(owner_address: address, can_delete: bool): ConstructorRef acquires Tombstone {
- let unique_address = transaction_context::generate_unique_address();
- create_object_internal(owner_address, unique_address, can_delete)
+public(friend) fun create_user_derived_object(
+ creator_address: address, derive_ref: &DeriveRef, can_delete: bool
+): ConstructorRef acquires Tombstone {
+ let obj_addr =
+ create_user_derived_object_address(creator_address, derive_ref.self);
+ create_object_internal(
+ creator_address,
+ obj_addr,
+ can_delete
+ )
}
-
-
-
+
-## Function `create_object_internal`
+## Function `create_object`
+Create a new object by generating a random unique address based on transaction hash.
+The unique address is computed sha3_256([transaction hash | auid counter | 0xFB]).
-fun create_object_internal(creator_address: address, object: address, can_delete: bool): object::ConstructorRef
+public fun create_object(owner_address: address, can_delete: bool): object::ConstructorRef
-
-Implementation
+##### Implementation
-fun create_object_internal(
- creator_address: address,
- object: address,
- can_delete: bool,
+public fun create_object(
+ owner_address: address, can_delete: bool
): ConstructorRef acquires Tombstone {
- // create resource account to prevent address overapping.
- account::create_object_account(object);
-
- assert!(!exists<ObjectCore>(object), error::already_exists(EOBJECT_EXISTS));
- let object_signer = account::create_signer(object);
- let version = if (exists<Tombstone>(object)) {
- let Tombstone { version } = move_from<Tombstone>(object);
- (version+1)
- } else {
- 1
- };
-
- move_to(
- &object_signer,
- ObjectCore {
- owner: creator_address,
- allow_ungated_transfer: true,
- version,
- },
- );
-
- event::emit (
- CreateEvent {
- owner: creator_address,
- object,
- version,
- }
- );
-
- ConstructorRef { self: object, version, can_delete }
+ let unique_address = transaction_context::generate_unique_address();
+ create_object_internal(
+ owner_address,
+ unique_address,
+ can_delete
+ )
}
-
-
## Function `generate_delete_ref`
@@ -1000,20 +931,20 @@ Generates the DeleteRef, which can be used to remove ObjectCore from global stor
-
-Implementation
+##### Implementation
public fun generate_delete_ref(ref: &ConstructorRef): DeleteRef {
- assert!(ref.can_delete, error::permission_denied(ECANNOT_DELETE));
+ assert!(
+ ref.can_delete,
+ error::permission_denied(ECANNOT_DELETE)
+ );
DeleteRef { self: ref.self, version: ref.version }
}
-
-
## Function `generate_extend_ref`
@@ -1026,8 +957,7 @@ Generates the ExtendRef, which can be used to add new events and resources to th
-
-Implementation
+##### Implementation
public fun generate_extend_ref(ref: &ConstructorRef): ExtendRef {
@@ -1037,8 +967,6 @@ Generates the ExtendRef, which can be used to add new events and resources to th
-
-
## Function `generate_transfer_ref`
@@ -1051,8 +979,7 @@ Generates the TransferRef, which can be used to manage object transfers.
-
-Implementation
+##### Implementation
public fun generate_transfer_ref(ref: &ConstructorRef): TransferRef {
@@ -1062,8 +989,6 @@ Generates the TransferRef, which can be used to manage object transfers.
-
-
## Function `generate_derive_ref`
@@ -1076,8 +1001,7 @@ Generates the DeriveRef, which can be used to create determnistic derived object
-
-Implementation
+##### Implementation
public fun generate_derive_ref(ref: &ConstructorRef): DeriveRef {
@@ -1087,8 +1011,6 @@ Generates the DeriveRef, which can be used to create determnistic derived object
-
-
## Function `generate_signer`
@@ -1101,8 +1023,7 @@ Create a signer for the ConstructorRef
-
-Implementation
+##### Implementation
public fun generate_signer(ref: &ConstructorRef): signer {
@@ -1112,8 +1033,6 @@ Create a signer for the ConstructorRef
-
-
## Function `address_from_constructor_ref`
@@ -1126,8 +1045,7 @@ Returns the address associated with the constructor
-
-Implementation
+##### Implementation
public fun address_from_constructor_ref(ref: &ConstructorRef): address {
@@ -1137,8 +1055,6 @@ Returns the address associated with the constructor
-
-
## Function `object_from_constructor_ref`
@@ -1151,8 +1067,7 @@ Returns an Object from within a ConstructorRef
-
-Implementation
+##### Implementation
public fun object_from_constructor_ref<T: key>(ref: &ConstructorRef): Object<T> {
@@ -1162,8 +1077,6 @@ Returns an Object from within a ConstructorRef
-
-
## Function `can_generate_delete_ref`
@@ -1176,8 +1089,7 @@ Returns whether or not the ConstructorRef can be used to create DeleteRef
-
-Implementation
+##### Implementation
public fun can_generate_delete_ref(ref: &ConstructorRef): bool {
@@ -1187,8 +1099,6 @@ Returns whether or not the ConstructorRef can be used to create DeleteRef
-
-
## Function `address_from_delete_ref`
@@ -1201,8 +1111,7 @@ Returns the address associated with the constructor
-
-Implementation
+##### Implementation
public fun address_from_delete_ref(ref: &DeleteRef): address {
@@ -1212,8 +1121,6 @@ Returns the address associated with the constructor
-
-
## Function `object_from_delete_ref`
@@ -1226,8 +1133,7 @@ Returns an Object from within a DeleteRef.
-
-Implementation
+##### Implementation
public fun object_from_delete_ref<T: key>(ref: &DeleteRef): Object<T> {
@@ -1237,8 +1143,6 @@ Returns an Object from within a DeleteRef.
-
-
## Function `delete`
@@ -1251,31 +1155,28 @@ Removes from the specified Object from global storage.
-
-Implementation
+##### Implementation
public fun delete(ref: DeleteRef) acquires ObjectCore {
let object_core = move_from<ObjectCore>(ref.self);
- assert!(ref.version == object_core.version, error::permission_denied(EVERSION_MISMATCH));
+ assert!(
+ ref.version == object_core.version,
+ error::permission_denied(EVERSION_MISMATCH)
+ );
- let ObjectCore {
- owner: _,
- allow_ungated_transfer: _,
- version,
- } = object_core;
+ let ObjectCore { owner: _, allow_ungated_transfer: _, version } = object_core;
// set tombstone
- move_to<Tombstone>(&account::create_signer(ref.self), Tombstone {
- version,
- });
+ move_to<Tombstone>(
+ &account::create_signer(ref.self),
+ Tombstone { version }
+ );
}
-
-
## Function `generate_signer_for_extending`
@@ -1288,13 +1189,15 @@ Create a signer for the ExtendRef
-
-Implementation
+##### Implementation
public fun generate_signer_for_extending(ref: &ExtendRef): signer acquires ObjectCore {
let object_core = borrow_global<ObjectCore>(ref.self);
- assert!(ref.version == object_core.version, error::permission_denied(EVERSION_MISMATCH));
+ assert!(
+ ref.version == object_core.version,
+ error::permission_denied(EVERSION_MISMATCH)
+ );
account::create_signer(ref.self)
}
@@ -1302,8 +1205,6 @@ Create a signer for the ExtendRef
-
-
## Function `address_from_extend_ref`
@@ -1316,8 +1217,7 @@ Returns an address from within a ExtendRef.
-
-Implementation
+##### Implementation
public fun address_from_extend_ref(ref: &ExtendRef): address {
@@ -1327,8 +1227,6 @@ Returns an address from within a ExtendRef.
-
-
## Function `disable_ungated_transfer`
@@ -1341,13 +1239,15 @@ Disable direct transfer, transfers can only be triggered via a TransferRef
-
-Implementation
+##### Implementation
public fun disable_ungated_transfer(ref: &TransferRef) acquires ObjectCore {
let object_core = borrow_global_mut<ObjectCore>(ref.self);
- assert!(ref.version == object_core.version, error::permission_denied(EVERSION_MISMATCH));
+ assert!(
+ ref.version == object_core.version,
+ error::permission_denied(EVERSION_MISMATCH)
+ );
object_core.allow_ungated_transfer = false;
}
@@ -1355,8 +1255,6 @@ Disable direct transfer, transfers can only be triggered via a TransferRef
-
-
## Function `enable_ungated_transfer`
@@ -1369,13 +1267,15 @@ Enable direct transfer.
-
-Implementation
+##### Implementation
public fun enable_ungated_transfer(ref: &TransferRef) acquires ObjectCore {
let object_core = borrow_global_mut<ObjectCore>(ref.self);
- assert!(ref.version == object_core.version, error::permission_denied(EVERSION_MISMATCH));
+ assert!(
+ ref.version == object_core.version,
+ error::permission_denied(EVERSION_MISMATCH)
+ );
object_core.allow_ungated_transfer = true;
}
@@ -1383,8 +1283,6 @@ Enable direct transfer.
-
-
## Function `generate_linear_transfer_ref`
@@ -1398,26 +1296,28 @@ time of generation is the owner at the time of transferring.
-
-Implementation
+##### Implementation
-public fun generate_linear_transfer_ref(ref: &TransferRef): LinearTransferRef acquires ObjectCore {
+public fun generate_linear_transfer_ref(
+ ref: &TransferRef
+): LinearTransferRef acquires ObjectCore {
let object_core = borrow_global<ObjectCore>(ref.self);
- assert!(ref.version == object_core.version, error::permission_denied(EVERSION_MISMATCH));
+ assert!(
+ ref.version == object_core.version,
+ error::permission_denied(EVERSION_MISMATCH)
+ );
LinearTransferRef {
self: ref.self,
owner: object_core.owner,
- version: object_core.version,
+ version: object_core.version
}
}
-
-
## Function `transfer_with_ref`
@@ -1430,22 +1330,21 @@ Transfer to the destination address using a LinearTransferRef.
-
-Implementation
+##### Implementation
public fun transfer_with_ref(ref: LinearTransferRef, to: address) acquires ObjectCore {
let object_core = borrow_global_mut<ObjectCore>(ref.self);
- assert!(ref.version == object_core.version, error::permission_denied(EVERSION_MISMATCH));
- assert!(object_core.owner == ref.owner, error::permission_denied(ENOT_OBJECT_OWNER));
-
- event::emit(
- TransferEvent {
- object: ref.self,
- from: object_core.owner,
- to,
- },
+ assert!(
+ ref.version == object_core.version,
+ error::permission_denied(EVERSION_MISMATCH)
);
+ assert!(
+ object_core.owner == ref.owner,
+ error::permission_denied(ENOT_OBJECT_OWNER)
+ );
+
+ event::emit(TransferEvent { object: ref.self, from: object_core.owner, to });
object_core.owner = to;
}
@@ -1453,8 +1352,6 @@ Transfer to the destination address using a LinearTransferRef.
-
-
## Function `transfer_call`
@@ -1467,14 +1364,11 @@ Entry function that can be used to transfer, if allow_ungated_transfer is set tr
-
-Implementation
+##### Implementation
public entry fun transfer_call(
- owner: &signer,
- object: address,
- to: address,
+ owner: &signer, object: address, to: address
) acquires ObjectCore {
transfer_raw(owner, object, to)
}
@@ -1482,8 +1376,6 @@ Entry function that can be used to transfer, if allow_ungated_transfer is set tr
-
-
## Function `transfer`
@@ -1497,14 +1389,11 @@ for Object to the "to" address.
-
-Implementation
+##### Implementation
public entry fun transfer<T: key>(
- owner: &signer,
- object: Object<T>,
- to: address,
+ owner: &signer, object: Object<T>, to: address
) acquires ObjectCore {
transfer_raw(owner, object.inner, to)
}
@@ -1512,8 +1401,6 @@ for Object to the "to" address.
-
-
## Function `transfer_raw`
@@ -1529,38 +1416,23 @@ hierarchy.
-
-Implementation
+##### Implementation
-public fun transfer_raw(
- owner: &signer,
- object: address,
- to: address,
-) acquires ObjectCore {
+public fun transfer_raw(owner: &signer, object: address, to: address) acquires ObjectCore {
let owner_address = signer::address_of(owner);
verify_ungated_and_descendant(owner_address, object);
let object_core = borrow_global_mut<ObjectCore>(object);
- if (object_core.owner == to) {
- return
- };
+ if (object_core.owner == to) { return };
- event::emit(
- TransferEvent {
- object: object,
- from: object_core.owner,
- to,
- },
- );
+ event::emit(TransferEvent { object: object, from: object_core.owner, to });
object_core.owner = to;
}
-
-
## Function `transfer_to_object`
@@ -1573,14 +1445,11 @@ Transfer the given object to another object. See transfer
for more
-
-Implementation
+##### Implementation
public entry fun transfer_to_object<O: key, T: key>(
- owner: &signer,
- object: Object<O>,
- to: Object<T>,
+ owner: &signer, object: Object<O>, to: Object<T>
) acquires ObjectCore {
transfer(owner, object, to.inner)
}
@@ -1588,67 +1457,6 @@ Transfer the given object to another object. See transfer
for more
-
-
-
-
-## Function `verify_ungated_and_descendant`
-
-This checks that the destination address is eventually owned by the owner and that each
-object between the two allows for ungated transfers. Note, this is limited to a depth of 8
-objects may have cyclic dependencies.
-
-
-fun verify_ungated_and_descendant(owner: address, destination: address)
-
-
-
-
-
-Implementation
-
-
-fun verify_ungated_and_descendant(owner: address, destination: address) acquires ObjectCore {
- let current_address = destination;
- assert!(
- exists<ObjectCore>(current_address),
- error::not_found(EOBJECT_DOES_NOT_EXIST),
- );
-
- let object = borrow_global<ObjectCore>(current_address);
- assert!(
- object.allow_ungated_transfer,
- error::permission_denied(ENO_UNGATED_TRANSFERS),
- );
-
- let current_address = object.owner;
-
- let count = 0;
- while (owner != current_address) {
- let count = count + 1;
- assert!(count < MAXIMUM_OBJECT_NESTING, error::out_of_range(EMAXIMUM_NESTING));
-
- // At this point, the first object exists and so the more likely case is that the
- // object's owner is not an object. So we return a more sensible error.
- assert!(
- exists<ObjectCore>(current_address),
- error::permission_denied(ENOT_OBJECT_OWNER),
- );
- let object = borrow_global<ObjectCore>(current_address);
- assert!(
- object.allow_ungated_transfer,
- error::permission_denied(ENO_UNGATED_TRANSFERS),
- );
-
- current_address = object.owner;
- };
-}
-
-
-
-
-
-
## Function `ungated_transfer_allowed`
@@ -1662,14 +1470,13 @@ Return true if ungated transfer is allowed.
-
-Implementation
+##### Implementation
public fun ungated_transfer_allowed<T: key>(object: Object<T>): bool acquires ObjectCore {
assert!(
exists<ObjectCore>(object.inner),
- error::not_found(EOBJECT_DOES_NOT_EXIST),
+ error::not_found(EOBJECT_DOES_NOT_EXIST)
);
borrow_global<ObjectCore>(object.inner).allow_ungated_transfer
}
@@ -1677,8 +1484,6 @@ Return true if ungated transfer is allowed.
-
-
## Function `owner`
@@ -1692,14 +1497,13 @@ Return the current owner.
-
-Implementation
+##### Implementation
public fun owner<T: key>(object: Object<T>): address acquires ObjectCore {
assert!(
exists<ObjectCore>(object.inner),
- error::not_found(EOBJECT_DOES_NOT_EXIST),
+ error::not_found(EOBJECT_DOES_NOT_EXIST)
);
borrow_global<ObjectCore>(object.inner).owner
}
@@ -1707,8 +1511,6 @@ Return the current owner.
-
-
## Function `is_owner`
@@ -1722,8 +1524,7 @@ Return true if the provided address is the current owner.
-
-Implementation
+##### Implementation
public fun is_owner<T: key>(object: Object<T>, owner: address): bool acquires ObjectCore {
@@ -1733,8 +1534,6 @@ Return true if the provided address is the current owner.
-
-
## Function `owns`
@@ -1748,19 +1547,18 @@ Return true if the provided address has indirect or direct ownership of the prov
-
-Implementation
+##### Implementation
public fun owns<T: key>(object: Object<T>, owner: address): bool acquires ObjectCore {
- let current_address = object_address(object);
+ let current_address = object_address(&object);
if (current_address == owner) {
return true
};
assert!(
exists<ObjectCore>(current_address),
- error::not_found(EOBJECT_DOES_NOT_EXIST),
+ error::not_found(EOBJECT_DOES_NOT_EXIST)
);
let object = borrow_global<ObjectCore>(current_address);
@@ -1768,8 +1566,11 @@ Return true if the provided address has indirect or direct ownership of the prov
let count = 0;
while (owner != current_address) {
- let count = count + 1;
- assert!(count < MAXIMUM_OBJECT_NESTING, error::out_of_range(EMAXIMUM_NESTING));
+ count = count + 1;
+ assert!(
+ count < MAXIMUM_OBJECT_NESTING,
+ error::out_of_range(EMAXIMUM_NESTING)
+ );
if (!exists<ObjectCore>(current_address)) {
return false
};
@@ -1780,7 +1581,3 @@ Return true if the provided address has indirect or direct ownership of the prov
true
}
-
-
-
-
diff --git a/initia_stdlib/doc/object_code_deployment.md b/initia_stdlib/doc/object_code_deployment.md
new file mode 100644
index 0000000..8e0d276
--- /dev/null
+++ b/initia_stdlib/doc/object_code_deployment.md
@@ -0,0 +1,316 @@
+
+
+
+# Module `0x1::object_code_deployment`
+
+This module allows users to deploy, upgrade and freeze modules deployed to objects on-chain.
+This enables users to deploy modules to an object with a unique address each time they are published.
+This modules provides an alternative method to publish code on-chain, where code is deployed to objects rather than accounts.
+This is encouraged as it abstracts the necessary resources needed for deploying modules,
+along with the required authorization to upgrade and freeze modules.
+
+The functionalities of this module are as follows.
+
+Publishing modules flow:
+1. Create a new object with the address derived from the publisher address and the object seed.
+2. Publish the module passed in the function via metadata_serialized
and code
to the newly created object.
+3. Emits 'Publish' event with the address of the newly created object.
+4. Create a ManagingRefs
which stores the extend ref of the newly created object.
+Note: This is needed to upgrade the code as the signer must be generated to upgrade the existing code in an object.
+
+Upgrading modules flow:
+1. Assert the code_object
passed in the function is owned by the publisher
.
+2. Assert the code_object
passed in the function exists in global storage.
+2. Retrieve the ExtendRef
from the code_object
and generate the signer from this.
+3. Upgrade the module with the metadata_serialized
and code
passed in the function.
+4. Emits 'Upgrade' event with the address of the object with the upgraded code.
+Note: If the modules were deployed as immutable when calling publish
, the upgrade will fail.
+
+Freezing modules flow:
+1. Assert the code_object
passed in the function exists in global storage.
+2. Assert the code_object
passed in the function is owned by the publisher
.
+3. Mark all the modules in the code_object
as immutable.
+4. Emits 'Freeze' event with the address of the object with the frozen code.
+Note: There is no unfreeze function as this gives no benefit if the user can freeze/unfreeze modules at will.
+Once modules are marked as immutable, they cannot be made mutable again.
+
+
+- [Resource `ManagingRefs`](#0x1_object_code_deployment_ManagingRefs)
+- [Struct `Publish`](#0x1_object_code_deployment_Publish)
+- [Struct `Upgrade`](#0x1_object_code_deployment_Upgrade)
+- [Struct `Freeze`](#0x1_object_code_deployment_Freeze)
+- [Constants](#@Constants_0)
+- [Function `publish`](#0x1_object_code_deployment_publish)
+- [Function `upgrade`](#0x1_object_code_deployment_upgrade)
+- [Function `freeze_code_object`](#0x1_object_code_deployment_freeze_code_object)
+
+
+use 0x1::account;
+use 0x1::bcs;
+use 0x1::code;
+use 0x1::error;
+use 0x1::event;
+use 0x1::object;
+use 0x1::signer;
+use 0x1::string;
+use 0x1::vector;
+
+
+
+
+
+
+## Resource `ManagingRefs`
+
+Internal struct, attached to the object, that holds Refs we need to manage the code deployment (i.e. upgrades).
+
+
+struct ManagingRefs has key
+
+
+
+
+##### Fields
+
+
+
+-
+
extend_ref: object::ExtendRef
+
+-
+ We need to keep the extend ref to be able to generate the signer to upgrade existing code.
+
+
+
+
+
+
+## Struct `Publish`
+
+Event emitted when code is published to an object.
+
+
+#[event]
+struct Publish has drop, store
+
+
+
+
+##### Fields
+
+
+
+-
+
object_address: address
+
+-
+
+
+
+
+
+
+
+## Struct `Upgrade`
+
+Event emitted when code in an existing object is upgraded.
+
+
+#[event]
+struct Upgrade has drop, store
+
+
+
+
+##### Fields
+
+
+
+-
+
object_address: address
+
+-
+
+
+
+
+
+
+
+## Struct `Freeze`
+
+Event emitted when code in an existing object is made immutable.
+
+
+#[event]
+struct Freeze has drop, store
+
+
+
+
+##### Fields
+
+
+
+-
+
object_address: address
+
+-
+
+
+
+
+
+
+
+## Constants
+
+
+
+
+code_object
does not exist.
+
+
+const ECODE_OBJECT_DOES_NOT_EXIST: u64 = 3;
+
+
+
+
+
+
+Not the owner of the code_object
+
+
+const ENOT_CODE_OBJECT_OWNER: u64 = 2;
+
+
+
+
+
+
+Object code deployment feature not supported.
+
+
+const EOBJECT_CODE_DEPLOYMENT_NOT_SUPPORTED: u64 = 1;
+
+
+
+
+
+
+
+
+const OBJECT_CODE_DEPLOYMENT_DOMAIN_SEPARATOR: vector<u8> = [105, 110, 105, 116, 105, 97, 95, 115, 116, 100, 58, 58, 111, 98, 106, 101, 99, 116, 95, 99, 111, 100, 101, 95, 100, 101, 112, 108, 111, 121, 109, 101, 110, 116];
+
+
+
+
+
+
+## Function `publish`
+
+Creates a new object with a unique address derived from the publisher address and the object seed.
+Publishes the code passed in the function to the newly created object.
+The caller must provide package metadata describing the package via metadata_serialized
and
+the code to be published via code
. This contains a vector of modules to be deployed on-chain.
+
+
+public entry fun publish(publisher: &signer, module_ids: vector<string::String>, code: vector<vector<u8>>)
+
+
+
+
+##### Implementation
+
+
+public entry fun publish(
+ publisher: &signer, module_ids: vector<String>, code: vector<vector<u8>>
+) {
+ let publisher_address = signer::address_of(publisher);
+ let object_seed = object_seed(publisher_address);
+ let constructor_ref = &object::create_named_object(publisher, object_seed);
+ let code_signer = &object::generate_signer(constructor_ref);
+ code::publish(code_signer, module_ids, code, 1);
+
+ event::emit(Publish { object_address: signer::address_of(code_signer) });
+
+ move_to(
+ code_signer,
+ ManagingRefs { extend_ref: object::generate_extend_ref(constructor_ref) }
+ );
+}
+
+
+
+
+
+
+## Function `upgrade`
+
+Upgrades the existing modules at the code_object
address with the new modules passed in code
,
+along with the metadata metadata_serialized
.
+Note: If the modules were deployed as immutable when calling publish
, the upgrade will fail.
+Requires the publisher to be the owner of the code_object
.
+
+
+public entry fun upgrade(publisher: &signer, module_ids: vector<string::String>, code: vector<vector<u8>>, code_object: object::Object<code::MetadataStore>)
+
+
+
+
+##### Implementation
+
+
+public entry fun upgrade(
+ publisher: &signer,
+ module_ids: vector<String>,
+ code: vector<vector<u8>>,
+ code_object: Object<MetadataStore>
+) acquires ManagingRefs {
+ let publisher_address = signer::address_of(publisher);
+ assert!(
+ object::is_owner(code_object, publisher_address),
+ error::permission_denied(ENOT_CODE_OBJECT_OWNER)
+ );
+
+ let code_object_address = object::object_address(&code_object);
+ assert!(
+ exists<ManagingRefs>(code_object_address),
+ error::not_found(ECODE_OBJECT_DOES_NOT_EXIST)
+ );
+
+ let extend_ref = &borrow_global<ManagingRefs>(code_object_address).extend_ref;
+ let code_signer = &object::generate_signer_for_extending(extend_ref);
+ code::publish(code_signer, module_ids, code, 1);
+
+ event::emit(Upgrade { object_address: signer::address_of(code_signer) });
+}
+
+
+
+
+
+
+## Function `freeze_code_object`
+
+Make an existing upgradable package immutable. Once this is called, the package cannot be made upgradable again.
+Each code_object
should only have one package, as one package is deployed per object in this module.
+Requires the publisher
to be the owner of the code_object
.
+
+
+public entry fun freeze_code_object(publisher: &signer, code_object: object::Object<code::MetadataStore>)
+
+
+
+
+##### Implementation
+
+
+public entry fun freeze_code_object(
+ publisher: &signer, code_object: Object<MetadataStore>
+) {
+ code::freeze_code_object(publisher, code_object);
+
+ event::emit(Freeze { object_address: object::object_address(&code_object) });
+}
+
diff --git a/initia_stdlib/doc/operator.md b/initia_stdlib/doc/operator.md
deleted file mode 100644
index ba97666..0000000
--- a/initia_stdlib/doc/operator.md
+++ /dev/null
@@ -1,612 +0,0 @@
-
-
-
-# Module `0x1::vip_operator`
-
-
-
-- [Resource `OperatorStore`](#0x1_vip_operator_OperatorStore)
-- [Struct `OperatorStoreResponse`](#0x1_vip_operator_OperatorStoreResponse)
-- [Struct `UpdateCommissionEvent`](#0x1_vip_operator_UpdateCommissionEvent)
-- [Constants](#@Constants_0)
-- [Function `check_chain_permission`](#0x1_vip_operator_check_chain_permission)
-- [Function `check_valid_rate`](#0x1_vip_operator_check_valid_rate)
-- [Function `is_valid_commission_rates`](#0x1_vip_operator_is_valid_commission_rates)
-- [Function `register_operator_store`](#0x1_vip_operator_register_operator_store)
-- [Function `update_operator_commission`](#0x1_vip_operator_update_operator_commission)
-- [Function `generate_operator_store_seed`](#0x1_vip_operator_generate_operator_store_seed)
-- [Function `create_operator_store_address`](#0x1_vip_operator_create_operator_store_address)
-- [Function `is_operator_store_registered`](#0x1_vip_operator_is_operator_store_registered)
-- [Function `get_operator_store_address`](#0x1_vip_operator_get_operator_store_address)
-- [Function `get_operator_store`](#0x1_vip_operator_get_operator_store)
-- [Function `get_operator_commission`](#0x1_vip_operator_get_operator_commission)
-
-
-use 0x1::bcs;
-use 0x1::decimal256;
-use 0x1::error;
-use 0x1::event;
-use 0x1::object;
-use 0x1::signer;
-use 0x1::vector;
-
-
-
-
-
-
-## Resource `OperatorStore`
-
-
-
-struct OperatorStore has key
-
-
-
-
-
-Fields
-
-
-
--
-
last_changed_stage: u64
-
--
-
-
--
-
commission_max_rate: decimal256::Decimal256
-
--
-
-
--
-
commission_max_change_rate: decimal256::Decimal256
-
--
-
-
--
-
commission_rate: decimal256::Decimal256
-
--
-
-
-
-
-
-
-
-
-
-## Struct `OperatorStoreResponse`
-
-
-
-struct OperatorStoreResponse has drop
-
-
-
-
-
-Fields
-
-
-
--
-
last_changed_stage: u64
-
--
-
-
--
-
commission_max_rate: decimal256::Decimal256
-
--
-
-
--
-
commission_max_change_rate: decimal256::Decimal256
-
--
-
-
--
-
commission_rate: decimal256::Decimal256
-
--
-
-
-
-
-
-
-
-
-
-## Struct `UpdateCommissionEvent`
-
-
-
-#[event]
-struct UpdateCommissionEvent has drop, store
-
-
-
-
-
-Fields
-
-
-
--
-
operator: address
-
--
-
-
--
-
bridge_id: u64
-
--
-
-
--
-
stage: u64
-
--
-
-
--
-
commission_rate: decimal256::Decimal256
-
--
-
-
-
-
-
-
-
-
-
-## Constants
-
-
-
-
-
-
-const EUNAUTHORIZED: u64 = 7;
-
-
-
-
-
-
-
-
-const EINVALID_STAGE: u64 = 5;
-
-
-
-
-
-
-
-
-const EINVALID_COMMISSION_CHANGE_RATE: u64 = 3;
-
-
-
-
-
-
-
-
-const EINVALID_COMMISSION_RATE: u64 = 6;
-
-
-
-
-
-
-
-
-const EOPERATOR_STORE_ALREADY_EXISTS: u64 = 1;
-
-
-
-
-
-
-
-
-const EOPERATOR_STORE_NOT_FOUND: u64 = 2;
-
-
-
-
-
-
-
-
-const EOVER_MAX_COMMISSION_RATE: u64 = 4;
-
-
-
-
-
-
-
-
-const OPERATOR_STORE_PREFIX: u8 = 246;
-
-
-
-
-
-
-## Function `check_chain_permission`
-
-
-
-fun check_chain_permission(chain: &signer)
-
-
-
-
-
-Implementation
-
-
-fun check_chain_permission(chain: &signer) {
- assert!(signer::address_of(chain) == @initia_std, error::permission_denied(EUNAUTHORIZED));
-}
-
-
-
-
-
-
-
-
-## Function `check_valid_rate`
-
-
-
-fun check_valid_rate(rate: &decimal256::Decimal256)
-
-
-
-
-
-Implementation
-
-
-fun check_valid_rate(rate: &Decimal256) {
- assert!(
- decimal256::val(rate) <= decimal256::val(&decimal256::one()),
- error::invalid_argument(EINVALID_COMMISSION_RATE)
- );
-}
-
-
-
-
-
-
-
-
-## Function `is_valid_commission_rates`
-
-
-
-fun is_valid_commission_rates(commission_max_rate: &decimal256::Decimal256, commission_max_change_rate: &decimal256::Decimal256, commission_rate: &decimal256::Decimal256)
-
-
-
-
-
-Implementation
-
-
-fun is_valid_commission_rates(
- commission_max_rate: &Decimal256,
- commission_max_change_rate: &Decimal256,
- commission_rate: &Decimal256
-) {
- check_valid_rate(commission_max_rate);
- check_valid_rate(commission_max_change_rate);
- check_valid_rate(commission_rate);
- assert!(
- decimal256::val(commission_rate) <= decimal256::val(commission_max_rate),
- error::invalid_argument(EOVER_MAX_COMMISSION_RATE)
- );
-}
-
-
-
-
-
-
-
-
-## Function `register_operator_store`
-
-
-
-public(friend) fun register_operator_store(chain: &signer, operator: address, bridge_id: u64, stage: u64, commission_max_rate: decimal256::Decimal256, commission_max_change_rate: decimal256::Decimal256, commission_rate: decimal256::Decimal256)
-
-
-
-
-
-Implementation
-
-
-public(friend) fun register_operator_store(
- chain: &signer,
- operator: address,
- bridge_id: u64,
- stage: u64,
- commission_max_rate: Decimal256,
- commission_max_change_rate: Decimal256,
- commission_rate: Decimal256
-) {
- check_chain_permission(chain);
- let seed = generate_operator_store_seed(operator, bridge_id);
- let operator_addr = object::create_object_address(signer::address_of(chain), seed);
- assert!(!exists<OperatorStore>(operator_addr), error::already_exists(EOPERATOR_STORE_ALREADY_EXISTS));
-
- is_valid_commission_rates(&commission_max_rate, &commission_max_change_rate, &commission_rate);
-
- let constructor_ref = object::create_named_object(chain, seed, false);
- let transfer_ref = object::generate_transfer_ref(&constructor_ref);
- object::disable_ungated_transfer(&transfer_ref);
- let object = object::generate_signer(&constructor_ref);
-
- let operator_store = OperatorStore {
- last_changed_stage: stage,
- commission_max_rate,
- commission_max_change_rate,
- commission_rate,
- };
- move_to(&object, operator_store);
-}
-
-
-
-
-
-
-
-
-## Function `update_operator_commission`
-
-
-
-public(friend) fun update_operator_commission(operator: &signer, bridge_id: u64, stage: u64, commission_rate: decimal256::Decimal256)
-
-
-
-
-
-Implementation
-
-
-public(friend) fun update_operator_commission(
- operator: &signer,
- bridge_id: u64,
- stage: u64,
- commission_rate: Decimal256
-) acquires OperatorStore {
- let operator_addr = signer::address_of(operator);
- let operator_store_addr = get_operator_store_address(operator_addr, bridge_id);
- let operator_store = borrow_global_mut<OperatorStore>(operator_store_addr);
-
- // commission can be updated once per a stage.
- assert!(stage > operator_store.last_changed_stage, error::invalid_argument(EINVALID_STAGE));
-
- let old_commission_rate = decimal256::val(&operator_store.commission_rate);
- let new_commission_rate = decimal256::val(&commission_rate);
- let max_commission_change_rate = decimal256::val(&operator_store.commission_max_change_rate);
- let max_commission_rate = decimal256::val(&operator_store.commission_max_rate);
-
- assert!(new_commission_rate <= max_commission_rate, error::invalid_argument(EOVER_MAX_COMMISSION_RATE));
-
- if (old_commission_rate > new_commission_rate) {
- let change = old_commission_rate - new_commission_rate;
- assert!(change <= max_commission_change_rate, error::invalid_argument(EINVALID_COMMISSION_CHANGE_RATE));
- } else {
- let change = new_commission_rate - old_commission_rate;
- assert!(change <= max_commission_change_rate, error::invalid_argument(EINVALID_COMMISSION_CHANGE_RATE));
- };
-
- operator_store.commission_rate = commission_rate;
- operator_store.last_changed_stage = stage;
-
- event::emit(
- UpdateCommissionEvent {
- operator: operator_addr,
- bridge_id: bridge_id,
- stage: operator_store.last_changed_stage,
- commission_rate
- }
- );
-}
-
-
-
-
-
-
-
-
-## Function `generate_operator_store_seed`
-
-
-
-fun generate_operator_store_seed(operator: address, bridge_id: u64): vector<u8>
-
-
-
-
-
-Implementation
-
-
-fun generate_operator_store_seed(operator:address, bridge_id: u64) : vector<u8> {
- let seed = vector[OPERATOR_STORE_PREFIX];
- vector::append(&mut seed, bcs::to_bytes(&operator));
- vector::append(&mut seed, bcs::to_bytes(&bridge_id));
- return seed
-}
-
-
-
-
-
-
-
-
-## Function `create_operator_store_address`
-
-
-
-fun create_operator_store_address(operator_addr: address, bridge_id: u64): address
-
-
-
-
-
-Implementation
-
-
-fun create_operator_store_address(operator_addr: address, bridge_id: u64): address {
- let seed = generate_operator_store_seed(operator_addr, bridge_id);
- object::create_object_address(@initia_std, seed)
-}
-
-
-
-
-
-
-
-
-## Function `is_operator_store_registered`
-
-
-
-#[view]
-public fun is_operator_store_registered(operator_addr: address, bridge_id: u64): bool
-
-
-
-
-
-Implementation
-
-
-public fun is_operator_store_registered(operator_addr: address, bridge_id: u64): bool {
- exists<OperatorStore>(create_operator_store_address(operator_addr, bridge_id))
-}
-
-
-
-
-
-
-
-
-## Function `get_operator_store_address`
-
-
-
-#[view]
-public fun get_operator_store_address(operator_addr: address, bridge_id: u64): address
-
-
-
-
-
-Implementation
-
-
-public fun get_operator_store_address(operator_addr: address, bridge_id: u64): address {
- let operator_store_addr = create_operator_store_address(operator_addr, bridge_id);
- assert!(exists<OperatorStore>(operator_store_addr), error::not_found(EOPERATOR_STORE_NOT_FOUND));
- operator_store_addr
-}
-
-
-
-
-
-
-
-
-## Function `get_operator_store`
-
-
-
-#[view]
-public fun get_operator_store(operator: address, bridge_id: u64): vip_operator::OperatorStoreResponse
-
-
-
-
-
-Implementation
-
-
-public fun get_operator_store(
- operator: address,
- bridge_id: u64
-): OperatorStoreResponse acquires OperatorStore {
- let operator_store_addr = get_operator_store_address(operator, bridge_id);
- let operator_store = borrow_global<OperatorStore>(operator_store_addr);
- OperatorStoreResponse {
- last_changed_stage: operator_store.last_changed_stage,
- commission_max_rate: operator_store.commission_max_rate,
- commission_max_change_rate: operator_store.commission_max_change_rate,
- commission_rate: operator_store.commission_rate,
- }
-}
-
-
-
-
-
-
-
-
-## Function `get_operator_commission`
-
-
-
-#[view]
-public fun get_operator_commission(operator: address, bridge_id: u64): decimal256::Decimal256
-
-
-
-
-
-Implementation
-
-
-public fun get_operator_commission(
- operator: address,
- bridge_id: u64
-): Decimal256 acquires OperatorStore {
- let operator_store_addr = get_operator_store_address(operator, bridge_id);
- let operator_store = borrow_global<OperatorStore>(operator_store_addr);
- operator_store.commission_rate
-}
-
-
-
-
-
diff --git a/initia_stdlib/doc/oracle.md b/initia_stdlib/doc/oracle.md
index 1631bd1..00f23d3 100644
--- a/initia_stdlib/doc/oracle.md
+++ b/initia_stdlib/doc/oracle.md
@@ -6,7 +6,6 @@
- [Function `get_price`](#0x1_oracle_get_price)
-- [Function `get_price_internal`](#0x1_oracle_get_price_internal)
use 0x1::string;
@@ -26,37 +25,10 @@
-
-Implementation
+##### Implementation
public fun get_price(pair_id: String): (u256, u64, u64) {
get_price_internal(*string::bytes(&pair_id))
}
-
-
-
-
-
-
-
-## Function `get_price_internal`
-
-
-
-fun get_price_internal(pair_id: vector<u8>): (u256, u64, u64)
-
-
-
-
-
-Implementation
-
-
-native fun get_price_internal(pair_id: vector<u8>): (u256, u64, u64);
-
-
-
-
-
diff --git a/initia_stdlib/doc/primary_fungible_store.md b/initia_stdlib/doc/primary_fungible_store.md
index f59873d..a28e034 100644
--- a/initia_stdlib/doc/primary_fungible_store.md
+++ b/initia_stdlib/doc/primary_fungible_store.md
@@ -21,7 +21,6 @@ fungible asset to it. This emits an deposit event.
- [Resource `DeriveRefPod`](#0x1_primary_fungible_store_DeriveRefPod)
- [Resource `ModuleStore`](#0x1_primary_fungible_store_ModuleStore)
- [Struct `PrimaryStoreCreatedEvent`](#0x1_primary_fungible_store_PrimaryStoreCreatedEvent)
-- [Function `init_module`](#0x1_primary_fungible_store_init_module)
- [Function `create_primary_store_enabled_fungible_asset`](#0x1_primary_fungible_store_create_primary_store_enabled_fungible_asset)
- [Function `ensure_primary_store_exists`](#0x1_primary_fungible_store_ensure_primary_store_exists)
- [Function `create_primary_store`](#0x1_primary_fungible_store_create_primary_store)
@@ -32,9 +31,12 @@ fungible asset to it. This emits an deposit event.
- [Function `is_frozen`](#0x1_primary_fungible_store_is_frozen)
- [Function `balance`](#0x1_primary_fungible_store_balance)
- [Function `balances`](#0x1_primary_fungible_store_balances)
+- [Function `sudo_deposit`](#0x1_primary_fungible_store_sudo_deposit)
+- [Function `sudo_transfer`](#0x1_primary_fungible_store_sudo_transfer)
- [Function `withdraw`](#0x1_primary_fungible_store_withdraw)
- [Function `deposit`](#0x1_primary_fungible_store_deposit)
- [Function `transfer`](#0x1_primary_fungible_store_transfer)
+- [Function `transfer_assert_minimum_deposit`](#0x1_primary_fungible_store_transfer_assert_minimum_deposit)
- [Function `mint`](#0x1_primary_fungible_store_mint)
- [Function `burn`](#0x1_primary_fungible_store_burn)
- [Function `set_frozen_flag`](#0x1_primary_fungible_store_set_frozen_flag)
@@ -44,6 +46,7 @@ fungible asset to it. This emits an deposit event.
use 0x1::account;
+use 0x1::dispatchable_fungible_asset;
use 0x1::event;
use 0x1::fungible_asset;
use 0x1::object;
@@ -69,8 +72,7 @@ assets.
-
-Fields
+##### Fields
@@ -83,8 +85,6 @@ assets.
-
-
## Resource `ModuleStore`
@@ -96,8 +96,7 @@ assets.
-
-Fields
+##### Fields
@@ -116,8 +115,6 @@ assets.
-
-
## Struct `PrimaryStoreCreatedEvent`
@@ -130,8 +127,7 @@ assets.
-
-Fields
+##### Fields
@@ -156,35 +152,6 @@ assets.
-
-
-
-
-## Function `init_module`
-
-
-
-fun init_module(chain: &signer)
-
-
-
-
-
-Implementation
-
-
-fun init_module (chain: &signer) {
- move_to(chain, ModuleStore {
- issuers: table::new(),
- user_stores: table::new(),
- })
-}
-
-
-
-
-
-
## Function `create_primary_store_enabled_fungible_asset`
@@ -199,8 +166,7 @@ so that users can easily deposit/withdraw/transfer fungible assets.
-
-Implementation
+##### Implementation
public fun create_primary_store_enabled_fungible_asset(
@@ -210,7 +176,7 @@ so that users can easily deposit/withdraw/transfer fungible assets.
symbol: String,
decimals: u8,
icon_uri: String,
- project_uri: String,
+ project_uri: String
) acquires ModuleStore {
fungible_asset::add_fungibility(
constructor_ref,
@@ -219,28 +185,32 @@ so that users can easily deposit/withdraw/transfer fungible assets.
symbol,
decimals,
icon_uri,
- project_uri,
+ project_uri
);
let metadata = object::object_from_constructor_ref<Metadata>(constructor_ref);
let metadata_signer = &object::generate_signer(constructor_ref);
- move_to(metadata_signer, DeriveRefPod {
- metadata_derive_ref: object::generate_derive_ref(constructor_ref),
- });
-
- let module_store = borrow_global_mut<ModuleStore>(@initia_std);
- table::add(
- &mut module_store.issuers,
- object::object_address(metadata),
- object::owner(metadata),
+ move_to(
+ metadata_signer,
+ DeriveRefPod {
+ metadata_derive_ref: object::generate_derive_ref(constructor_ref)
+ }
);
+
+ // record issuers for cosmos side query
+ if (exists<ModuleStore>(@initia_std)) {
+ let module_store = borrow_global_mut<ModuleStore>(@initia_std);
+ table::add(
+ &mut module_store.issuers,
+ object::object_address(&metadata),
+ object::owner(metadata)
+ );
+ }
}
-
-
## Function `ensure_primary_store_exists`
@@ -253,13 +223,11 @@ Ensure that the primary store object for the given address exists. If it doesn't
-
-Implementation
+##### Implementation
public fun ensure_primary_store_exists<T: key>(
- owner: address,
- metadata: Object<T>,
+ owner: address, metadata: Object<T>
): Object<FungibleStore> acquires DeriveRefPod, ModuleStore {
if (!primary_store_exists(owner, metadata)) {
create_primary_store(owner, metadata)
@@ -271,8 +239,6 @@ Ensure that the primary store object for the given address exists. If it doesn't
-
-
## Function `create_primary_store`
@@ -285,55 +251,62 @@ Create a primary store object to hold fungible asset for the given address.
-
-Implementation
+##### Implementation
public fun create_primary_store<T: key>(
- owner_addr: address,
- metadata: Object<T>,
+ owner_addr: address, metadata: Object<T>
): Object<FungibleStore> acquires DeriveRefPod, ModuleStore {
- let metadata_addr = object::object_address(metadata);
+ let metadata_addr = object::object_address(&metadata);
object::address_to_object<Metadata>(metadata_addr);
let derive_ref = &borrow_global<DeriveRefPod>(metadata_addr).metadata_derive_ref;
- let constructor_ref = &object::create_user_derived_object(owner_addr, derive_ref, false);
+ let constructor_ref =
+ &object::create_user_derived_object(owner_addr, derive_ref, false);
// Disable ungated transfer as deterministic stores shouldn't be transferrable.
let transfer_ref = &object::generate_transfer_ref(constructor_ref);
object::disable_ungated_transfer(transfer_ref);
let store = fungible_asset::create_store(constructor_ref, metadata);
+ let store_addr = object::address_from_constructor_ref(constructor_ref);
- // add owner store to table for balances query
- let module_store = borrow_global_mut<ModuleStore>(@initia_std);
- if (!table::contains(&module_store.user_stores, owner_addr)) {
- table::add(&mut module_store.user_stores, owner_addr, table::new());
+ // record owner store to table for cosmos side query
+ if (exists<ModuleStore>(@initia_std)) {
+ let module_store = borrow_global_mut<ModuleStore>(@initia_std);
+ if (!table::contains(
+ &module_store.user_stores,
+ owner_addr
+ )) {
+ table::add(
+ &mut module_store.user_stores,
+ owner_addr,
+ table::new()
+ );
+ };
+
+ let user_stores = table::borrow_mut(&mut module_store.user_stores, owner_addr);
+
+ table::add(
+ user_stores,
+ metadata_addr,
+ store_addr
+ );
};
- let user_stores = table::borrow_mut(&mut module_store.user_stores, owner_addr);
- let store_addr = object::address_from_constructor_ref(constructor_ref);
- table::add(user_stores, metadata_addr, store_addr);
-
// emit store created event
- event::emit(PrimaryStoreCreatedEvent {
- owner_addr,
- store_addr,
- metadata_addr,
- });
-
+ event::emit(PrimaryStoreCreatedEvent { owner_addr, store_addr, metadata_addr });
store
}
-
-
## Function `issuer`
+Get the address of the issuer for the given metadata object.
#[view]
@@ -342,20 +315,20 @@ Create a primary store object to hold fungible asset for the given address.
-
-Implementation
+##### Implementation
public fun issuer<T: key>(metadata: Object<T>): address acquires ModuleStore {
let module_store = borrow_global<ModuleStore>(@initia_std);
- *table::borrow(&module_store.issuers, object::object_address(metadata))
+ *table::borrow(
+ &module_store.issuers,
+ object::object_address(&metadata)
+ )
}
-
-
## Function `primary_store_address`
@@ -369,20 +342,19 @@ Get the address of the primary store for the given account.
-
-Implementation
+##### Implementation
-public fun primary_store_address<T: key>(owner: address, metadata: Object<T>): address {
- let metadata_addr = object::object_address(metadata);
+public fun primary_store_address<T: key>(
+ owner: address, metadata: Object<T>
+): address {
+ let metadata_addr = object::object_address(&metadata);
object::create_user_derived_object_address(owner, metadata_addr)
}
-
-
## Function `primary_store`
@@ -396,11 +368,11 @@ Get the primary store object for the given account.
-
-Implementation
+##### Implementation
-public fun primary_store<T: key>(owner: address, metadata: Object<T>): Object<FungibleStore> {
+public fun primary_store<T: key>(owner: address, metadata: Object<T>):
+ Object<FungibleStore> {
let store = primary_store_address(owner, metadata);
object::address_to_object<FungibleStore>(store)
}
@@ -408,8 +380,6 @@ Get the primary store object for the given account.
-
-
## Function `primary_store_exists`
@@ -423,19 +393,18 @@ Return whether the given account's primary store exists.
-
-Implementation
+##### Implementation
-public fun primary_store_exists<T: key>(account: address, metadata: Object<T>): bool {
+public fun primary_store_exists<T: key>(
+ account: address, metadata: Object<T>
+): bool {
fungible_asset::store_exists(primary_store_address(account, metadata))
}
-
-
## Function `is_frozen`
@@ -449,23 +418,18 @@ Return whether the given account's primary store is frozen.
-
-Implementation
+##### Implementation
public fun is_frozen<T: key>(account: address, metadata: Object<T>): bool {
if (primary_store_exists(account, metadata)) {
fungible_asset::is_frozen(primary_store(account, metadata))
- } else {
- false
- }
+ } else { false }
}
-
-
## Function `balance`
@@ -479,27 +443,23 @@ Get the balance of account
's p
-
-Implementation
+##### Implementation
public fun balance<T: key>(account: address, metadata: Object<T>): u64 {
if (primary_store_exists(account, metadata)) {
fungible_asset::balance(primary_store(account, metadata))
- } else {
- 0
- }
+ } else { 0 }
}
-
-
## Function `balances`
+Get the balances of account
's primary store of all fungible assets.
#[view]
@@ -508,34 +468,35 @@ Get the balance of account
's p
-
-Implementation
+##### Implementation
public fun balances(
- account: address,
- start_after: Option<address>,
- limit: u8,
-): (vector<Object<Metadata>>, vector<u64>) acquires ModuleStore {
+ account: address, start_after: Option<address>, limit: u8
+): (vector<Object<Metadata>>, vector<u64>) acquires ModuleStore {
let module_store = borrow_global<ModuleStore>(@initia_std);
let account_stores = table::borrow(&module_store.user_stores, account);
let iter = table::iter(
account_stores,
option::none(),
start_after,
- 2,
+ 2
);
let metadata_vec: vector<Object<Metadata>> = vector[];
let balance_vec: vector<u64> = vector[];
- while (table::prepare<address, address>(&mut iter) && vector::length(&balance_vec) < (limit as u64)) {
- let (metadata_addr, store_addr) = table::next<address, address>(&mut iter);
+ while (table::prepare<address, address>(iter)
+ && vector::length(&balance_vec) < (limit as u64)) {
+ let (metadata_addr, store_addr) = table::next<address, address>(iter);
let metadata = object::address_to_object<Metadata>(metadata_addr);
let store = object::address_to_object<FungibleStore>(*store_addr);
vector::push_back(&mut metadata_vec, metadata);
- vector::push_back(&mut balance_vec, fungible_asset::balance(store));
+ vector::push_back(
+ &mut balance_vec,
+ fungible_asset::balance(store)
+ );
};
(metadata_vec, balance_vec)
@@ -544,7 +505,75 @@ Get the balance of account
's p
-
+
+
+## Function `sudo_deposit`
+
+Deposit fungible asset fa
to the given account's primary store.
+
+This function is only callable by the chain.
+
+
+public(friend) fun sudo_deposit(owner: address, fa: fungible_asset::FungibleAsset)
+
+
+
+
+##### Implementation
+
+
+public(friend) fun sudo_deposit(
+ owner: address, fa: FungibleAsset
+) acquires DeriveRefPod, ModuleStore {
+ let metadata = fungible_asset::asset_metadata(&fa);
+ let store = ensure_primary_store_exists(owner, metadata);
+ fungible_asset::sudo_deposit(store, fa);
+
+ // create cosmos side account
+ if (!account::exists_at(owner)) {
+ let _acc_num = account::create_account(owner);
+ };
+}
+
+
+
+
+
+
+## Function `sudo_transfer`
+
+Transfer amount
of fungible asset from sender's primary store to receiver's primary store.
+
+This function is only callable by the chain.
+
+
+public(friend) fun sudo_transfer<T: key>(sender: &signer, metadata: object::Object<T>, recipient: address, amount: u64)
+
+
+
+
+##### Implementation
+
+
+public(friend) fun sudo_transfer<T: key>(
+ sender: &signer,
+ metadata: Object<T>,
+ recipient: address,
+ amount: u64
+) acquires DeriveRefPod, ModuleStore {
+ let sender_store =
+ ensure_primary_store_exists(signer::address_of(sender), metadata);
+ let recipient_store = ensure_primary_store_exists(recipient, metadata);
+ fungible_asset::sudo_transfer(
+ sender,
+ sender_store,
+ recipient_store,
+ amount
+ );
+}
+
+
+
@@ -558,20 +587,23 @@ Withdraw amount
of fungible asset from the given account's primary
-
-Implementation
+##### Implementation
-public fun withdraw<T: key>(owner: &signer, metadata: Object<T>, amount: u64): FungibleAsset {
+public fun withdraw<T: key>(
+ owner: &signer, metadata: Object<T>, amount: u64
+): FungibleAsset {
+ if (amount == 0) {
+ return fungible_asset::zero(metadata)
+ };
+
let store = primary_store(signer::address_of(owner), metadata);
- fungible_asset::withdraw(owner, store, amount)
+ dispatchable_fungible_asset::withdraw(owner, store, amount)
}
-
-
## Function `deposit`
@@ -584,14 +616,13 @@ Deposit fungible asset fa
to the given account's primary store.
-
-Implementation
+##### Implementation
public fun deposit(owner: address, fa: FungibleAsset) acquires DeriveRefPod, ModuleStore {
let metadata = fungible_asset::asset_metadata(&fa);
let store = ensure_primary_store_exists(owner, metadata);
- fungible_asset::deposit(store, fa);
+ dispatchable_fungible_asset::deposit(store, fa);
// create cosmos side account
if (!account::exists_at(owner)) {
@@ -602,8 +633,6 @@ Deposit fungible asset fa
to the given account's primary store.
-
-
## Function `transfer`
@@ -616,25 +645,68 @@ Transfer amount
of fungible asset from sender's primary store to re
-
-Implementation
+##### Implementation
public entry fun transfer<T: key>(
sender: &signer,
metadata: Object<T>,
recipient: address,
- amount: u64,
+ amount: u64
) acquires DeriveRefPod, ModuleStore {
- let sender_store = ensure_primary_store_exists(signer::address_of(sender), metadata);
+ let sender_store =
+ ensure_primary_store_exists(signer::address_of(sender), metadata);
let recipient_store = ensure_primary_store_exists(recipient, metadata);
- fungible_asset::transfer(sender, sender_store, recipient_store, amount);
+ dispatchable_fungible_asset::transfer(
+ sender, sender_store, recipient_store, amount
+ );
+
+ // create cosmos side account
+ if (!account::exists_at(recipient)) {
+ let _acc_num = account::create_account(recipient);
+ };
}
-
+
+
+## Function `transfer_assert_minimum_deposit`
+
+Transfer amount
of fungible asset from sender's primary store to receiver's primary store.
+Use the minimum deposit assertion api to make sure receipient will receive a minimum amount of fund.
+
+
+public entry fun transfer_assert_minimum_deposit<T: key>(sender: &signer, metadata: object::Object<T>, recipient: address, amount: u64, expected: u64)
+
+
+
+
+##### Implementation
+
+
+public entry fun transfer_assert_minimum_deposit<T: key>(
+ sender: &signer,
+ metadata: Object<T>,
+ recipient: address,
+ amount: u64,
+ expected: u64
+) acquires DeriveRefPod, ModuleStore {
+ let sender_store =
+ ensure_primary_store_exists(signer::address_of(sender), metadata);
+ let recipient_store = ensure_primary_store_exists(recipient, metadata);
+ dispatchable_fungible_asset::transfer_assert_minimum_deposit(
+ sender,
+ sender_store,
+ recipient_store,
+ amount,
+ expected
+ );
+}
+
+
+
@@ -648,20 +720,27 @@ Mint to the primary store of owner
.
-
-Implementation
+##### Implementation
public fun mint(mint_ref: &MintRef, owner: address, amount: u64) acquires DeriveRefPod, ModuleStore {
- let primary_store = ensure_primary_store_exists(owner, fungible_asset::mint_ref_metadata(mint_ref));
+ let primary_store =
+ ensure_primary_store_exists(
+ owner,
+ fungible_asset::mint_ref_metadata(mint_ref)
+ );
+
fungible_asset::mint_to(mint_ref, primary_store, amount);
+
+ // create cosmos side account
+ if (!account::exists_at(owner)) {
+ let _acc_num = account::create_account(owner);
+ };
}
-
-
## Function `burn`
@@ -674,20 +753,21 @@ Burn from the primary store of owner
.
-
-Implementation
+##### Implementation
public fun burn(burn_ref: &BurnRef, owner: address, amount: u64) {
- let primary_store = primary_store(owner, fungible_asset::burn_ref_metadata(burn_ref));
+ let primary_store =
+ primary_store(
+ owner,
+ fungible_asset::burn_ref_metadata(burn_ref)
+ );
fungible_asset::burn_from(burn_ref, primary_store, amount);
}
-
-
## Function `set_frozen_flag`
@@ -700,20 +780,23 @@ Freeze/Unfreeze the primary store of owner
.
-
-Implementation
+##### Implementation
-public fun set_frozen_flag(transfer_ref: &TransferRef, owner: address, frozen: bool) acquires DeriveRefPod, ModuleStore {
- let primary_store = ensure_primary_store_exists(owner, fungible_asset::transfer_ref_metadata(transfer_ref));
+public fun set_frozen_flag(
+ transfer_ref: &TransferRef, owner: address, frozen: bool
+) acquires DeriveRefPod, ModuleStore {
+ let primary_store =
+ ensure_primary_store_exists(
+ owner,
+ fungible_asset::transfer_ref_metadata(transfer_ref)
+ );
fungible_asset::set_frozen_flag(transfer_ref, primary_store, frozen);
}
-
-
## Function `withdraw_with_ref`
@@ -726,20 +809,27 @@ Withdraw from the primary store of owner
ignoring frozen flag.
-
-Implementation
+##### Implementation
-public fun withdraw_with_ref(transfer_ref: &TransferRef, owner: address, amount: u64): FungibleAsset {
- let from_primary_store = primary_store(owner, fungible_asset::transfer_ref_metadata(transfer_ref));
- fungible_asset::withdraw_with_ref(transfer_ref, from_primary_store, amount)
+public fun withdraw_with_ref(
+ transfer_ref: &TransferRef, owner: address, amount: u64
+): FungibleAsset {
+ let from_primary_store =
+ primary_store(
+ owner,
+ fungible_asset::transfer_ref_metadata(transfer_ref)
+ );
+ fungible_asset::withdraw_with_ref(
+ transfer_ref,
+ from_primary_store,
+ amount
+ )
}
-
-
## Function `deposit_with_ref`
@@ -752,23 +842,28 @@ Deposit from the primary store of owner
ignoring frozen flag.
-
-Implementation
+##### Implementation
-public fun deposit_with_ref(transfer_ref: &TransferRef, owner: address, fa: FungibleAsset) acquires DeriveRefPod, ModuleStore {
- let from_primary_store = ensure_primary_store_exists(
- owner,
- fungible_asset::transfer_ref_metadata(transfer_ref)
- );
+public fun deposit_with_ref(
+ transfer_ref: &TransferRef, owner: address, fa: FungibleAsset
+) acquires DeriveRefPod, ModuleStore {
+ let from_primary_store =
+ ensure_primary_store_exists(
+ owner,
+ fungible_asset::transfer_ref_metadata(transfer_ref)
+ );
fungible_asset::deposit_with_ref(transfer_ref, from_primary_store, fa);
+
+ // create cosmos side account
+ if (!account::exists_at(owner)) {
+ let _acc_num = account::create_account(owner);
+ };
}
-
-
## Function `transfer_with_ref`
@@ -781,8 +876,7 @@ Transfer amount
of FA from the primary store of from
t
-
-Implementation
+##### Implementation
public fun transfer_with_ref(
@@ -791,12 +885,26 @@ Transfer amount
of FA from the primary store of from
t
to: address,
amount: u64
) acquires DeriveRefPod, ModuleStore {
- let from_primary_store = primary_store(from, fungible_asset::transfer_ref_metadata(transfer_ref));
- let to_primary_store = ensure_primary_store_exists(to, fungible_asset::transfer_ref_metadata(transfer_ref));
- fungible_asset::transfer_with_ref(transfer_ref, from_primary_store, to_primary_store, amount);
+ let from_primary_store =
+ primary_store(
+ from,
+ fungible_asset::transfer_ref_metadata(transfer_ref)
+ );
+ let to_primary_store =
+ ensure_primary_store_exists(
+ to,
+ fungible_asset::transfer_ref_metadata(transfer_ref)
+ );
+ fungible_asset::transfer_with_ref(
+ transfer_ref,
+ from_primary_store,
+ to_primary_store,
+ amount
+ );
+
+ // create cosmos side account
+ if (!account::exists_at(to)) {
+ let _acc_num = account::create_account(to);
+ };
}
-
-
-
-
diff --git a/initia_stdlib/doc/property_map.md b/initia_stdlib/doc/property_map.md
index 1ae505e..cb7a15f 100644
--- a/initia_stdlib/doc/property_map.md
+++ b/initia_stdlib/doc/property_map.md
@@ -15,16 +15,10 @@ represent types and storing values in bcs format.
- [Function `init`](#0x1_property_map_init)
- [Function `burn`](#0x1_property_map_burn)
- [Function `prepare_input`](#0x1_property_map_prepare_input)
-- [Function `to_external_type`](#0x1_property_map_to_external_type)
-- [Function `to_internal_type`](#0x1_property_map_to_internal_type)
-- [Function `type_info_to_internal_type`](#0x1_property_map_type_info_to_internal_type)
-- [Function `validate_type`](#0x1_property_map_validate_type)
- [Function `generate_mutator_ref`](#0x1_property_map_generate_mutator_ref)
- [Function `contains_key`](#0x1_property_map_contains_key)
- [Function `length`](#0x1_property_map_length)
- [Function `read`](#0x1_property_map_read)
-- [Function `assert_exists`](#0x1_property_map_assert_exists)
-- [Function `read_typed`](#0x1_property_map_read_typed)
- [Function `read_bool`](#0x1_property_map_read_bool)
- [Function `read_u8`](#0x1_property_map_read_u8)
- [Function `read_u16`](#0x1_property_map_read_u16)
@@ -37,10 +31,8 @@ represent types and storing values in bcs format.
- [Function `read_string`](#0x1_property_map_read_string)
- [Function `add`](#0x1_property_map_add)
- [Function `add_typed`](#0x1_property_map_add_typed)
-- [Function `add_internal`](#0x1_property_map_add_internal)
- [Function `update`](#0x1_property_map_update)
- [Function `update_typed`](#0x1_property_map_update_typed)
-- [Function `update_internal`](#0x1_property_map_update_internal)
- [Function `remove`](#0x1_property_map_remove)
@@ -70,8 +62,7 @@ should keep track of what keys are what types, and parse them accordingly.
-
-Fields
+##### Fields
@@ -84,8 +75,6 @@ should keep track of what keys are what types, and parse them accordingly.
-
-
## Struct `PropertyValue`
@@ -98,8 +87,7 @@ A typed value for the
-
-
## Struct `MutatorRef`
@@ -132,8 +118,7 @@ A mutator ref that allows for mutation of the property map
-
-Fields
+##### Fields
@@ -146,8 +131,6 @@ A mutator ref that allows for mutation of the property map
-
-
## Constants
@@ -354,8 +337,7 @@ Maximum number of characters in a property name
-
-Implementation
+##### Implementation
public fun init(s: &signer, container: PropertyMap) {
@@ -365,8 +347,6 @@ Maximum number of characters in a property name
-
-
## Function `burn`
@@ -380,8 +360,7 @@ TODO: hanlde when table is not empty
-
-Implementation
+##### Implementation
public fun burn(ref: MutatorRef) acquires PropertyMap {
@@ -391,8 +370,6 @@ TODO: hanlde when table is not empty
-
-
## Function `prepare_input`
@@ -405,26 +382,34 @@ Helper for external entry functions to produce a valid container for property va
-
-Implementation
+##### Implementation
public fun prepare_input(
keys: vector<String>,
types: vector<String>,
- values: vector<vector<u8>>,
+ values: vector<vector<u8>>
): PropertyMap {
let length = vector::length(&keys);
- assert!(length <= MAX_PROPERTY_MAP_SIZE, error::invalid_argument(ETOO_MANY_PROPERTIES));
- assert!(length == vector::length(&values), error::invalid_argument(EKEY_VALUE_COUNT_MISMATCH));
- assert!(length == vector::length(&types), error::invalid_argument(EKEY_TYPE_COUNT_MISMATCH));
+ assert!(
+ length <= MAX_PROPERTY_MAP_SIZE,
+ error::invalid_argument(ETOO_MANY_PROPERTIES)
+ );
+ assert!(
+ length == vector::length(&values),
+ error::invalid_argument(EKEY_VALUE_COUNT_MISMATCH)
+ );
+ assert!(
+ length == vector::length(&types),
+ error::invalid_argument(EKEY_TYPE_COUNT_MISMATCH)
+ );
let container = simple_map::create<String, PropertyValue>();
while (!vector::is_empty(&keys)) {
let key = vector::pop_back(&mut keys);
assert!(
string::length(&key) <= MAX_PROPERTY_NAME_LENGTH,
- error::invalid_argument(EPROPERTY_MAP_KEY_TOO_LONG),
+ error::invalid_argument(EPROPERTY_MAP_KEY_TOO_LONG)
);
let value = vector::pop_back(&mut values);
@@ -433,7 +418,11 @@ Helper for external entry functions to produce a valid container for property va
let new_type = to_internal_type(type);
validate_type(new_type, value);
- simple_map::add(&mut container, key, PropertyValue { value, type: new_type });
+ simple_map::add(
+ &mut container,
+ key,
+ PropertyValue { value, type: new_type }
+ );
};
PropertyMap { inner: container }
@@ -442,175 +431,6 @@ Helper for external entry functions to produce a valid container for property va
-
-
-
-
-## Function `to_external_type`
-
-Maps String
representation of types from their u8
representation
-
-
-fun to_external_type(type: u8): string::String
-
-
-
-
-
-Implementation
-
-
-inline fun to_external_type(type: u8): String {
- if (type == BOOL) {
- string::utf8(b"bool")
- } else if (type == U8) {
- string::utf8(b"u8")
- } else if (type == U16) {
- string::utf8(b"u16")
- } else if (type == U32) {
- string::utf8(b"u32")
- } else if (type == U64) {
- string::utf8(b"u64")
- } else if (type == U128) {
- string::utf8(b"u128")
- } else if (type == U256) {
- string::utf8(b"u256")
- } else if (type == ADDRESS) {
- string::utf8(b"address")
- } else if (type == BYTE_VECTOR) {
- string::utf8(b"vector<u8>")
- } else if (type == STRING) {
- string::utf8(b"0x1::string::String")
- } else {
- abort (error::invalid_argument(ETYPE_INVALID))
- }
-}
-
-
-
-
-
-
-
-
-## Function `to_internal_type`
-
-Maps the String
representation of types to u8
-
-
-fun to_internal_type(type: string::String): u8
-
-
-
-
-
-Implementation
-
-
-inline fun to_internal_type(type: String): u8 {
- if (type == string::utf8(b"bool")) {
- BOOL
- } else if (type == string::utf8(b"u8")) {
- U8
- } else if (type == string::utf8(b"u16")) {
- U16
- } else if (type == string::utf8(b"u32")) {
- U32
- } else if (type == string::utf8(b"u64")) {
- U64
- } else if (type == string::utf8(b"u128")) {
- U128
- } else if (type == string::utf8(b"u256")) {
- U256
- } else if (type == string::utf8(b"address")) {
- ADDRESS
- } else if (type == string::utf8(b"vector<u8>")) {
- BYTE_VECTOR
- } else if (type == string::utf8(b"0x1::string::String")) {
- STRING
- } else {
- abort (error::invalid_argument(ETYPE_INVALID))
- }
-}
-
-
-
-
-
-
-
-
-## Function `type_info_to_internal_type`
-
-Maps Move type to u8
representation
-
-
-fun type_info_to_internal_type<T>(): u8
-
-
-
-
-
-Implementation
-
-
-inline fun type_info_to_internal_type<T>(): u8 {
- let type = type_info::type_name<T>();
- to_internal_type(type)
-}
-
-
-
-
-
-
-
-
-## Function `validate_type`
-
-Validates property value type against its expected type
-
-
-fun validate_type(type: u8, value: vector<u8>)
-
-
-
-
-
-Implementation
-
-
-inline fun validate_type(type: u8, value: vector<u8>) {
- if (type == BOOL) {
- from_bcs::to_bool(value);
- } else if (type == U8) {
- from_bcs::to_u8(value);
- } else if (type == U16) {
- from_bcs::to_u16(value);
- } else if (type == U32) {
- from_bcs::to_u32(value);
- } else if (type == U64) {
- from_bcs::to_u64(value);
- } else if (type == U128) {
- from_bcs::to_u128(value);
- } else if (type == U256) {
- from_bcs::to_u256(value);
- } else if (type == ADDRESS) {
- from_bcs::to_address(value);
- } else if (type == BYTE_VECTOR) {
- // nothing to validate...
- } else if (type == STRING) {
- from_bcs::to_string(value);
- } else {
- abort (error::invalid_argument(ETYPE_MISMATCH))
- };
-}
-
-
-
-
-
-
## Function `generate_mutator_ref`
@@ -622,8 +442,7 @@ Validates property value type against its expected type
-
-Implementation
+##### Implementation
public fun generate_mutator_ref(s: &signer): MutatorRef {
@@ -633,8 +452,6 @@ Validates property value type against its expected type
-
-
## Function `contains_key`
@@ -646,21 +463,18 @@ Validates property value type against its expected type
-
-Implementation
+##### Implementation
public fun contains_key<T: key>(object: Object<T>, key: &String): bool acquires PropertyMap {
- assert_exists(object::object_address(object));
- let property_map = borrow_global<PropertyMap>(object::object_address(object));
+ assert_exists(object::object_address(&object));
+ let property_map = borrow_global<PropertyMap>(object::object_address(&object));
simple_map::contains_key(&property_map.inner, key)
}
-
-
## Function `length`
@@ -672,21 +486,18 @@ Validates property value type against its expected type
-
-Implementation
+##### Implementation
public fun length<T: key>(object: Object<T>): u64 acquires PropertyMap {
- assert_exists(object::object_address(object));
- let property_map = borrow_global<PropertyMap>(object::object_address(object));
+ assert_exists(object::object_address(&object));
+ let property_map = borrow_global<PropertyMap>(object::object_address(&object));
simple_map::length(&property_map.inner)
}
-
-
## Function `read`
@@ -701,13 +512,12 @@ The preferred method is to use read_<type>
where the type is
-
-Implementation
+##### Implementation
public fun read<T: key>(object: Object<T>, key: &String): (String, vector<u8>) acquires PropertyMap {
- assert_exists(object::object_address(object));
- let property_map = borrow_global<PropertyMap>(object::object_address(object));
+ assert_exists(object::object_address(&object));
+ let property_map = borrow_global<PropertyMap>(object::object_address(&object));
let property_value = simple_map::borrow(&property_map.inner, key);
let new_type = to_external_type(property_value.type);
(new_type, property_value.value)
@@ -716,65 +526,6 @@ The preferred method is to use read_<type>
where the type is
-
-
-
-
-## Function `assert_exists`
-
-
-
-fun assert_exists(object: address)
-
-
-
-
-
-Implementation
-
-
-inline fun assert_exists(object: address) {
- assert!(
- exists<PropertyMap>(object),
- error::not_found(EPROPERTY_MAP_DOES_NOT_EXIST),
- );
-}
-
-
-
-
-
-
-
-
-## Function `read_typed`
-
-Read a type and verify that the type is correct
-
-
-fun read_typed<T: key, V>(object: object::Object<T>, key: &string::String): vector<u8>
-
-
-
-
-
-Implementation
-
-
-inline fun read_typed<T: key, V>(object: Object<T>, key: &String): vector<u8> acquires PropertyMap {
- let (type, value) = read(object, key);
- assert!(
- type == type_info::type_name<V>(),
- error::invalid_argument(ETYPE_MISMATCH),
- );
- value
-}
-
-
-
-
-
-
## Function `read_bool`
@@ -786,8 +537,7 @@ Read a type and verify that the type is correct
-
-Implementation
+##### Implementation
public fun read_bool<T: key>(object: Object<T>, key: &String): bool acquires PropertyMap {
@@ -798,8 +548,6 @@ Read a type and verify that the type is correct
-
-
## Function `read_u8`
@@ -811,8 +559,7 @@ Read a type and verify that the type is correct
-
-Implementation
+##### Implementation
public fun read_u8<T: key>(object: Object<T>, key: &String): u8 acquires PropertyMap {
@@ -823,8 +570,6 @@ Read a type and verify that the type is correct
-
-
## Function `read_u16`
@@ -836,8 +581,7 @@ Read a type and verify that the type is correct
-
-Implementation
+##### Implementation
public fun read_u16<T: key>(object: Object<T>, key: &String): u16 acquires PropertyMap {
@@ -848,8 +592,6 @@ Read a type and verify that the type is correct
-
-
## Function `read_u32`
@@ -861,8 +603,7 @@ Read a type and verify that the type is correct
-
-Implementation
+##### Implementation
public fun read_u32<T: key>(object: Object<T>, key: &String): u32 acquires PropertyMap {
@@ -873,8 +614,6 @@ Read a type and verify that the type is correct
-
-
## Function `read_u64`
@@ -886,8 +625,7 @@ Read a type and verify that the type is correct
-
-Implementation
+##### Implementation
public fun read_u64<T: key>(object: Object<T>, key: &String): u64 acquires PropertyMap {
@@ -898,8 +636,6 @@ Read a type and verify that the type is correct
-
-
## Function `read_u128`
@@ -911,8 +647,7 @@ Read a type and verify that the type is correct
-
-Implementation
+##### Implementation
public fun read_u128<T: key>(object: Object<T>, key: &String): u128 acquires PropertyMap {
@@ -923,8 +658,6 @@ Read a type and verify that the type is correct
-
-
## Function `read_u256`
@@ -936,8 +669,7 @@ Read a type and verify that the type is correct
-
-Implementation
+##### Implementation
public fun read_u256<T: key>(object: Object<T>, key: &String): u256 acquires PropertyMap {
@@ -948,8 +680,6 @@ Read a type and verify that the type is correct
-
-
## Function `read_address`
@@ -961,8 +691,7 @@ Read a type and verify that the type is correct
-
-Implementation
+##### Implementation
public fun read_address<T: key>(object: Object<T>, key: &String): address acquires PropertyMap {
@@ -973,8 +702,6 @@ Read a type and verify that the type is correct
-
-
## Function `read_bytes`
@@ -986,8 +713,7 @@ Read a type and verify that the type is correct
-
-Implementation
+##### Implementation
public fun read_bytes<T: key>(object: Object<T>, key: &String): vector<u8> acquires PropertyMap {
@@ -998,8 +724,6 @@ Read a type and verify that the type is correct
-
-
## Function `read_string`
@@ -1011,8 +735,7 @@ Read a type and verify that the type is correct
-
-Implementation
+##### Implementation
public fun read_string<T: key>(object: Object<T>, key: &String): String acquires PropertyMap {
@@ -1023,8 +746,6 @@ Read a type and verify that the type is correct
-
-
## Function `add`
@@ -1037,11 +758,15 @@ Add a property, already bcs encoded as a add(ref: &MutatorRef, key: String, type: String, value: vector<u8>) acquires PropertyMap {
+public fun add(
+ ref: &MutatorRef,
+ key: String,
+ type: String,
+ value: vector<u8>
+) acquires PropertyMap {
let new_type = to_internal_type(type);
validate_type(new_type, value);
add_internal(ref, key, new_type, value);
@@ -1050,8 +775,6 @@ Add a property, already bcs encoded as a
## Function `add_typed`
@@ -1064,8 +787,7 @@ Add a property that isn't already encoded as a add_typed<T: drop>(ref: &MutatorRef, key: String, value: T) acquires PropertyMap {
@@ -1076,34 +798,6 @@ Add a property that isn't already encoded as a
-
-## Function `add_internal`
-
-
-
-fun add_internal(ref: &property_map::MutatorRef, key: string::String, type: u8, value: vector<u8>)
-
-
-
-
-
-Implementation
-
-
-inline fun add_internal(ref: &MutatorRef, key: String, type: u8, value: vector<u8>) acquires PropertyMap {
- assert_exists(ref.self);
- let property_map = borrow_global_mut<PropertyMap>(ref.self);
- simple_map::add(&mut property_map.inner, key, PropertyValue { type, value });
-}
-
-
-
-
-
-
## Function `update`
@@ -1116,11 +810,15 @@ Updates a property in place already bcs encoded
-
-Implementation
+##### Implementation
-public fun update(ref: &MutatorRef, key: &String, type: String, value: vector<u8>) acquires PropertyMap {
+public fun update(
+ ref: &MutatorRef,
+ key: &String,
+ type: String,
+ value: vector<u8>
+) acquires PropertyMap {
let new_type = to_internal_type(type);
validate_type(new_type, value);
update_internal(ref, key, new_type, value);
@@ -1129,8 +827,6 @@ Updates a property in place already bcs encoded
-
-
## Function `update_typed`
@@ -1143,11 +839,12 @@ Updates a property in place that is not already bcs encoded
-
-Implementation
+##### Implementation
-public fun update_typed<T: drop>(ref: &MutatorRef, key: &String, value: T) acquires PropertyMap {
+public fun update_typed<T: drop>(
+ ref: &MutatorRef, key: &String, value: T
+) acquires PropertyMap {
let type = type_info_to_internal_type<T>();
update_internal(ref, key, type, bcs::to_bytes(&value));
}
@@ -1155,35 +852,6 @@ Updates a property in place that is not already bcs encoded
-
-
-
-
-## Function `update_internal`
-
-
-
-fun update_internal(ref: &property_map::MutatorRef, key: &string::String, type: u8, value: vector<u8>)
-
-
-
-
-
-Implementation
-
-
-inline fun update_internal(ref: &MutatorRef, key: &String, type: u8, value: vector<u8>) acquires PropertyMap {
- assert_exists(ref.self);
- let property_map = borrow_global_mut<PropertyMap>(ref.self);
- let old_value = simple_map::borrow_mut(&mut property_map.inner, key);
- *old_value = PropertyValue { type, value };
-}
-
-
-
-
-
-
## Function `remove`
@@ -1196,8 +864,7 @@ Removes a property from the map, ensuring that it does in fact exist
-
-Implementation
+##### Implementation
public fun remove(ref: &MutatorRef, key: &String) acquires PropertyMap {
@@ -1206,7 +873,3 @@ Removes a property from the map, ensuring that it does in fact exist
simple_map::remove(&mut property_map.inner, key);
}
-
-
-
-
diff --git a/initia_stdlib/doc/query.md b/initia_stdlib/doc/query.md
index c040ef4..31fb327 100644
--- a/initia_stdlib/doc/query.md
+++ b/initia_stdlib/doc/query.md
@@ -5,6 +5,8 @@
+- [Struct `ProposalRequest`](#0x1_query_ProposalRequest)
+- [Struct `ProposalResponse`](#0x1_query_ProposalResponse)
- [Function `get_proposal`](#0x1_query_get_proposal)
- [Function `get_proposal_status`](#0x1_query_get_proposal_status)
- [Function `query_custom`](#0x1_query_query_custom)
@@ -12,13 +14,89 @@
use 0x1::json;
-use 0x1::option;
-use 0x1::simple_json;
use 0x1::string;
+
+
+## Struct `ProposalRequest`
+
+
+
+struct ProposalRequest has copy, drop
+
+
+
+
+##### Fields
+
+
+
+-
+
proposal_id: u64
+
+-
+
+
+
+
+
+
+
+## Struct `ProposalResponse`
+
+
+
+struct ProposalResponse has copy, drop
+
+
+
+
+##### Fields
+
+
+
+-
+
id: u64
+
+-
+
+
+-
+
title: string::String
+
+-
+
+
+-
+
summary: string::String
+
+-
+
+
+-
+
status: string::String
+
+-
+
+
+-
+
submit_time: string::String
+
+-
+
+
+-
+
emergency: bool
+
+-
+
+
+
+
+
## Function `get_proposal`
@@ -31,40 +109,22 @@
-
-Implementation
+##### Implementation
public fun get_proposal(proposal_id: u64): (u64, String, String, String) {
- let obj = json::empty();
- let index = json::start_index();
- json::set_object(&mut obj, index, option::none<String>(), 1);
- json::set_int_raw(&mut obj, json::get_next_index(&index, 0), option::some(string::utf8(b"proposal_id")), true, (proposal_id as u256));
-
- let req = json::stringify(&obj);
- let response = query_stargate(b"/initia.gov.v1.Query/Proposal", *string::bytes(&req));
- let res = json::parse(string::utf8(response));
- let index = json::get_next_index(&index, 0);
-
- let cindex = json::find(&res, &index, &string::utf8(b"id"));
- let (_, data) = json::unpack_elem(json::borrow(&res, &cindex));
- let (_, id) = json::as_int(data);
-
- let cindex = json::find(&res, &index, &string::utf8(b"title"));
- let (_, data) = json::unpack_elem(json::borrow(&res, &cindex));
- let title = json::as_string(data);
-
- let cindex = json::find(&res, &index, &string::utf8(b"summary"));
- let (_, data) = json::unpack_elem(json::borrow(&res, &cindex));
- let summary = json::as_string(data);
- ((id as u64), title, summary, string::utf8(response))
+ let response =
+ query_stargate(
+ b"/initia.gov.v1.Query/Proposal",
+ json::marshal(&ProposalRequest { proposal_id })
+ );
+ let res = json::unmarshal<ProposalResponse>(response);
+ (res.id, res.title, res.summary, string::utf8(response))
}
-
-
## Function `get_proposal_status`
@@ -77,45 +137,22 @@
-
-Implementation
+##### Implementation
public fun get_proposal_status(proposal_id: u64): (u64, String, String, bool) {
- let obj = simple_json::empty();
- simple_json::set_object(&mut obj, option::none<String>());
- simple_json::increase_depth(&mut obj);
- simple_json::set_int_raw(&mut obj, option::some(string::utf8(b"proposal_id")), true, (proposal_id as u256));
-
- let req = json::stringify(simple_json::to_json_object(&obj));
- let res = query_stargate(b"/initia.gov.v1.Query/Proposal", *string::bytes(&req));
- let res = simple_json::from_json_object(json::parse(string::utf8(res)));
- simple_json::increase_depth(&mut res);
- simple_json::increase_depth(&mut res);
-
- simple_json::find_and_set_index(&mut res, &string::utf8(b"id"));
- let (_, data) = json::unpack_elem(simple_json::borrow(&mut res));
- let (_, id) = json::as_int(data);
-
- simple_json::find_and_set_index(&mut res, &string::utf8(b"status"));
- let (_, data) = json::unpack_elem(simple_json::borrow(&mut res));
- let status = json::as_string(data);
-
- simple_json::find_and_set_index(&mut res, &string::utf8(b"submit_time"));
- let (_, data) = json::unpack_elem(simple_json::borrow(&mut res));
- let submit_time = json::as_string(data);
-
- simple_json::find_and_set_index(&mut res, &string::utf8(b"emergency"));
- let (_, data) = json::unpack_elem(simple_json::borrow(&mut res));
- let emergency = json::as_bool(data);
- ((id as u64), status, submit_time, emergency)
+ let response =
+ query_stargate(
+ b"/initia.gov.v1.Query/Proposal",
+ json::marshal(&ProposalRequest { proposal_id })
+ );
+ let res = json::unmarshal<ProposalResponse>(response);
+ (res.id, res.status, res.submit_time, res.emergency)
}
-
-
## Function `query_custom`
@@ -128,8 +165,7 @@ query_custom examples are in initia_stdlib::address module
-
-Implementation
+##### Implementation
native public fun query_custom(name: vector<u8>, data: vector<u8>): vector<u8>;
@@ -137,8 +173,6 @@ query_custom examples are in initia_stdlib::address module
-
-
## Function `query_stargate`
@@ -150,13 +184,8 @@ query_custom examples are in initia_stdlib::address module
-
-Implementation
+##### Implementation
native public fun query_stargate(path: vector<u8>, data: vector<u8>): vector<u8>;
-
-
-
-
diff --git a/initia_stdlib/doc/reward.md b/initia_stdlib/doc/reward.md
deleted file mode 100644
index 4b04f54..0000000
--- a/initia_stdlib/doc/reward.md
+++ /dev/null
@@ -1,412 +0,0 @@
-
-
-
-# Module `0x1::vip_reward`
-
-
-
-- [Resource `RewardStore`](#0x1_vip_reward_RewardStore)
-- [Constants](#@Constants_0)
-- [Function `reward_metadata`](#0x1_vip_reward_reward_metadata)
-- [Function `generate_reward_store_seed`](#0x1_vip_reward_generate_reward_store_seed)
-- [Function `create_reward_store_address`](#0x1_vip_reward_create_reward_store_address)
-- [Function `register_reward_store`](#0x1_vip_reward_register_reward_store)
-- [Function `add_reward_per_stage`](#0x1_vip_reward_add_reward_per_stage)
-- [Function `withdraw`](#0x1_vip_reward_withdraw)
-- [Function `balance`](#0x1_vip_reward_balance)
-- [Function `get_stage_reward`](#0x1_vip_reward_get_stage_reward)
-- [Function `is_reward_store_registered`](#0x1_vip_reward_is_reward_store_registered)
-- [Function `get_reward_store_address`](#0x1_vip_reward_get_reward_store_address)
-
-
-use 0x1::bcs;
-use 0x1::coin;
-use 0x1::error;
-use 0x1::fungible_asset;
-use 0x1::object;
-use 0x1::primary_fungible_store;
-use 0x1::signer;
-use 0x1::string;
-use 0x1::table;
-use 0x1::table_key;
-use 0x1::type_info;
-use 0x1::vector;
-
-
-
-
-
-
-## Resource `RewardStore`
-
-
-
-struct RewardStore has key
-
-
-
-
-
-Fields
-
-
-
--
-
extend_ref: object::ExtendRef
-
--
-
-
--
-
reward_store: object::Object<fungible_asset::FungibleStore>
-
--
-
-
--
-
reward_per_stage: table::Table<vector<u8>, u64>
-
--
-
-
-
-
-
-
-
-
-
-## Constants
-
-
-
-
-
-
-const REWARD_SYMBOL: vector<u8> = [117, 105, 110, 105, 116];
-
-
-
-
-
-
-
-
-const EREWARD_STORE_ALREADY_EXISTS: u64 = 1;
-
-
-
-
-
-
-
-
-const EREWARD_STORE_NOT_FOUND: u64 = 2;
-
-
-
-
-
-
-
-
-const OPERATOR_REWARD_PREFIX: u8 = 242;
-
-
-
-
-
-
-
-
-const USER_REWARD_PREFIX: u8 = 243;
-
-
-
-
-
-
-## Function `reward_metadata`
-
-
-
-public fun reward_metadata(): object::Object<fungible_asset::Metadata>
-
-
-
-
-
-Implementation
-
-
-public fun reward_metadata(): Object<Metadata> {
- coin::metadata(@initia_std, string::utf8(REWARD_SYMBOL))
-}
-
-
-
-
-
-
-
-
-## Function `generate_reward_store_seed`
-
-
-
-fun generate_reward_store_seed<Vesting: copy, drop, store>(bridge_id: u64): vector<u8>
-
-
-
-
-
-Implementation
-
-
-fun generate_reward_store_seed<Vesting: copy + drop + store>(bridge_id: u64): vector<u8>{
- let seed = if (type_info::type_name<Vesting>() == string::utf8(b"0x1::vip_vesting::OperatorVesting")) {
- vector[OPERATOR_REWARD_PREFIX]
- } else {
- vector[USER_REWARD_PREFIX]
- };
-
- vector::append(&mut seed, bcs::to_bytes(&bridge_id));
- return seed
-}
-
-
-
-
-
-
-
-
-## Function `create_reward_store_address`
-
-
-
-fun create_reward_store_address<Vesting: copy, drop, store>(bridge_id: u64): address
-
-
-
-
-
-Implementation
-
-
-fun create_reward_store_address<Vesting: copy + drop + store>(bridge_id: u64): address {
- let seed = generate_reward_store_seed<Vesting>(bridge_id);
- object::create_object_address(@initia_std, seed)
-}
-
-
-
-
-
-
-
-
-## Function `register_reward_store`
-
-
-
-public(friend) fun register_reward_store<Vesting: copy, drop, store>(chain: &signer, bridge_id: u64)
-
-
-
-
-
-Implementation
-
-
-public(friend) fun register_reward_store<Vesting: copy + drop + store>(
- chain: &signer,
- bridge_id: u64,
-) {
- let seed = generate_reward_store_seed<Vesting>(bridge_id);
- let reward_store_addr = object::create_object_address(signer::address_of(chain), seed);
- assert!(!exists<RewardStore>(reward_store_addr), error::already_exists(EREWARD_STORE_ALREADY_EXISTS));
-
- let constructor_ref = object::create_named_object(chain, seed, false);
- let object = object::generate_signer(&constructor_ref);
- let extend_ref = object::generate_extend_ref(&constructor_ref);
- let reward_store = primary_fungible_store::ensure_primary_store_exists(reward_store_addr, reward_metadata());
-
- move_to(
- &object, RewardStore {
- extend_ref,
- reward_store,
- reward_per_stage: table::new<vector<u8>, u64>(),
- }
- );
-}
-
-
-
-
-
-
-
-
-## Function `add_reward_per_stage`
-
-
-
-public(friend) fun add_reward_per_stage(reward_store_addr: address, stage: u64, reward: u64)
-
-
-
-
-
-Implementation
-
-
-public(friend) fun add_reward_per_stage(
- reward_store_addr: address,
- stage: u64,
- reward: u64
-) acquires RewardStore {
- let reward_store = borrow_global_mut<RewardStore>(reward_store_addr);
- let stage_reward = table::borrow_mut_with_default(&mut reward_store.reward_per_stage, table_key::encode_u64(stage), 0);
- *stage_reward = *stage_reward + reward;
-}
-
-
-
-
-
-
-
-
-## Function `withdraw`
-
-
-
-public(friend) fun withdraw(reward_store_addr: address, amount: u64): fungible_asset::FungibleAsset
-
-
-
-
-
-Implementation
-
-
-public(friend) fun withdraw(
- reward_store_addr: address,
- amount: u64,
-): FungibleAsset acquires RewardStore {
- let reward_store = borrow_global<RewardStore>(reward_store_addr);
- let reward_signer = object::generate_signer_for_extending(&reward_store.extend_ref);
-
- fungible_asset::withdraw(&reward_signer, reward_store.reward_store, amount)
-}
-
-
-
-
-
-
-
-
-## Function `balance`
-
-
-
-#[view]
-public fun balance(reward_store_addr: address): u64
-
-
-
-
-
-Implementation
-
-
-public fun balance(reward_store_addr: address): u64 {
- primary_fungible_store::balance(reward_store_addr, reward_metadata())
-}
-
-
-
-
-
-
-
-
-## Function `get_stage_reward`
-
-
-
-#[view]
-public fun get_stage_reward(reward_store_addr: address, stage: u64): u64
-
-
-
-
-
-Implementation
-
-
-public fun get_stage_reward(reward_store_addr: address, stage: u64): u64 acquires RewardStore {
- let reward_store = borrow_global<RewardStore>(reward_store_addr);
-
- let stage_reward = table::borrow_with_default(&reward_store.reward_per_stage, table_key::encode_u64(stage), &0);
- *stage_reward
-}
-
-
-
-
-
-
-
-
-## Function `is_reward_store_registered`
-
-
-
-#[view]
-public fun is_reward_store_registered<Vesting: copy, drop, store>(bridge_id: u64): bool
-
-
-
-
-
-Implementation
-
-
-public fun is_reward_store_registered<Vesting: copy + drop + store>(bridge_id: u64): bool {
- exists<RewardStore>(create_reward_store_address<Vesting>(bridge_id))
-}
-
-
-
-
-
-
-
-
-## Function `get_reward_store_address`
-
-
-
-#[view]
-public fun get_reward_store_address<Vesting: copy, drop, store>(bridge_id: u64): address
-
-
-
-
-
-Implementation
-
-
-public fun get_reward_store_address<Vesting: copy + drop + store>(bridge_id: u64): address {
- let reward_addr = create_reward_store_address<Vesting>(bridge_id);
- assert!(exists<RewardStore>(reward_addr), error::not_found(EREWARD_STORE_NOT_FOUND));
- reward_addr
-}
-
-
-
-
-
diff --git a/initia_stdlib/doc/royalty.md b/initia_stdlib/doc/royalty.md
index a86eb49..d9776a3 100644
--- a/initia_stdlib/doc/royalty.md
+++ b/initia_stdlib/doc/royalty.md
@@ -22,7 +22,7 @@ royalty.
- [Function `payee_address`](#0x1_royalty_payee_address)
-use 0x1::decimal128;
+use 0x1::bigdecimal;
use 0x1::error;
use 0x1::object;
use 0x1::option;
@@ -44,13 +44,12 @@ Royalties are optional for a collection.
-
-Fields
+##### Fields
-
-
royalty: decimal128::Decimal128
+royalty: bigdecimal::BigDecimal
-
@@ -64,8 +63,6 @@ Royalties are optional for a collection.
-
-
## Struct `MutatorRef`
@@ -78,8 +75,7 @@ This enables creating or overwriting a
-
-
## Constants
@@ -141,8 +135,7 @@ Add a royalty, given a ConstructorRef.
-
-Implementation
+##### Implementation
public fun init(ref: &ConstructorRef, royalty: Royalty) {
@@ -153,8 +146,6 @@ Add a royalty, given a ConstructorRef.
-
-
## Function `update`
@@ -167,8 +158,7 @@ Set the royalty if it does not exist, replace it otherwise.
-
-Implementation
+##### Implementation
public fun update(mutator_ref: &MutatorRef, royalty: Royalty) acquires Royalty {
@@ -184,8 +174,6 @@ Set the royalty if it does not exist, replace it otherwise.
-
-
## Function `create`
@@ -193,17 +181,19 @@ Set the royalty if it does not exist, replace it otherwise.
Creates a new royalty, verifying that it is a valid percentage
-public fun create(royalty: decimal128::Decimal128, payee_address: address): royalty::Royalty
+public fun create(royalty: bigdecimal::BigDecimal, payee_address: address): royalty::Royalty
-
-Implementation
+##### Implementation
-public fun create(royalty: Decimal128, payee_address: address): Royalty {
- assert!(decimal128::val(&royalty) <= decimal128::val(&decimal128::one()), error::out_of_range(EROYALTY_EXCEEDS_MAXIMUM));
+public fun create(royalty: BigDecimal, payee_address: address): Royalty {
+ assert!(
+ bigdecimal::le(royalty, bigdecimal::one()),
+ error::out_of_range(EROYALTY_EXCEEDS_MAXIMUM)
+ );
Royalty { royalty, payee_address }
}
@@ -211,8 +201,6 @@ Creates a new royalty, verifying that it is a valid percentage
-
-
## Function `generate_mutator_ref`
@@ -224,8 +212,7 @@ Creates a new royalty, verifying that it is a valid percentage
-
-Implementation
+##### Implementation
public fun generate_mutator_ref(ref: ExtendRef): MutatorRef {
@@ -235,8 +222,6 @@ Creates a new royalty, verifying that it is a valid percentage
-
-
## Function `exists_at`
@@ -248,8 +233,7 @@ Creates a new royalty, verifying that it is a valid percentage
-
-Implementation
+##### Implementation
public fun exists_at(addr: address): bool {
@@ -259,8 +243,6 @@ Creates a new royalty, verifying that it is a valid percentage
-
-
## Function `delete`
@@ -272,20 +254,20 @@ Creates a new royalty, verifying that it is a valid percentage
-
-Implementation
+##### Implementation
public(friend) fun delete(addr: address) acquires Royalty {
- assert!(exists<Royalty>(addr), error::not_found(EROYALTY_DOES_NOT_EXIST));
+ assert!(
+ exists<Royalty>(addr),
+ error::not_found(EROYALTY_DOES_NOT_EXIST)
+ );
move_from<Royalty>(addr);
}
-
-
## Function `get`
@@ -297,12 +279,11 @@ Creates a new royalty, verifying that it is a valid percentage
-
-Implementation
+##### Implementation
public fun get<T: key>(maybe_royalty: Object<T>): Option<Royalty> acquires Royalty {
- let obj_addr = object::object_address(maybe_royalty);
+ let obj_addr = object::object_address(&maybe_royalty);
if (exists<Royalty>(obj_addr)) {
option::some(*borrow_global<Royalty>(obj_addr))
} else {
@@ -313,32 +294,27 @@ Creates a new royalty, verifying that it is a valid percentage
-
-
## Function `royalty`
-public fun royalty(royalty: &royalty::Royalty): decimal128::Decimal128
+public fun royalty(royalty: &royalty::Royalty): bigdecimal::BigDecimal
-
-Implementation
+##### Implementation
-public fun royalty(royalty: &Royalty): Decimal128 {
+public fun royalty(royalty: &Royalty): BigDecimal {
royalty.royalty
}
-
-
## Function `payee_address`
@@ -350,15 +326,10 @@ Creates a new royalty, verifying that it is a valid percentage
-
-Implementation
+##### Implementation
public fun payee_address(royalty: &Royalty): address {
royalty.payee_address
}
-
-
-
-
diff --git a/initia_stdlib/doc/secp256k1.md b/initia_stdlib/doc/secp256k1.md
index e64227d..d66c72a 100644
--- a/initia_stdlib/doc/secp256k1.md
+++ b/initia_stdlib/doc/secp256k1.md
@@ -6,17 +6,19 @@
This module implements ECDSA signatures based on the prime-order secp256k1 ellptic curve (i.e., cofactor is 1).
-- [Struct `PublicKey`](#0x1_secp256k1_PublicKey)
-- [Struct `Signature`](#0x1_secp256k1_Signature)
+- [Struct `ECDSARawPublicKey`](#0x1_secp256k1_ECDSARawPublicKey)
+- [Struct `ECDSACompressedPublicKey`](#0x1_secp256k1_ECDSACompressedPublicKey)
+- [Struct `ECDSASignature`](#0x1_secp256k1_ECDSASignature)
- [Constants](#@Constants_0)
-- [Function `public_key_from_bytes`](#0x1_secp256k1_public_key_from_bytes)
-- [Function `signature_from_bytes`](#0x1_secp256k1_signature_from_bytes)
-- [Function `public_key_to_bytes`](#0x1_secp256k1_public_key_to_bytes)
-- [Function `signature_to_bytes`](#0x1_secp256k1_signature_to_bytes)
-- [Function `verify`](#0x1_secp256k1_verify)
-- [Function `recover_public_key`](#0x1_secp256k1_recover_public_key)
-- [Function `verify_internal`](#0x1_secp256k1_verify_internal)
-- [Function `recover_public_key_internal`](#0x1_secp256k1_recover_public_key_internal)
+- [Function `ecdsa_signature_from_bytes`](#0x1_secp256k1_ecdsa_signature_from_bytes)
+- [Function `ecdsa_raw_public_key_from_64_bytes`](#0x1_secp256k1_ecdsa_raw_public_key_from_64_bytes)
+- [Function `ecdsa_raw_public_key_from_bytes`](#0x1_secp256k1_ecdsa_raw_public_key_from_bytes)
+- [Function `ecdsa_compressed_public_key_from_bytes`](#0x1_secp256k1_ecdsa_compressed_public_key_from_bytes)
+- [Function `ecdsa_raw_public_key_to_bytes`](#0x1_secp256k1_ecdsa_raw_public_key_to_bytes)
+- [Function `ecdsa_compressed_public_key_to_bytes`](#0x1_secp256k1_ecdsa_compressed_public_key_to_bytes)
+- [Function `ecdsa_signature_to_bytes`](#0x1_secp256k1_ecdsa_signature_to_bytes)
+- [Function `ecdsa_recover`](#0x1_secp256k1_ecdsa_recover)
+- [Function `ecdsa_recover_compressed`](#0x1_secp256k1_ecdsa_recover_compressed)
use 0x1::error;
@@ -25,21 +27,19 @@ This module implements ECDSA signatures based on the prime-order secp256k1 ellpt
-
+
-## Struct `PublicKey`
+## Struct `ECDSARawPublicKey`
-A secp256k1-based ECDSA public key.
-It can be raw or compressed public key.
+A 64-byte ECDSA public key.
-struct PublicKey has copy, drop, store
+struct ECDSARawPublicKey has copy, drop, store
-
-Fields
+##### Fields
@@ -52,22 +52,19 @@ It can be raw or compressed public key.
-
+
-
+## Struct `ECDSACompressedPublicKey`
-## Struct `Signature`
+A 33-byte ECDSA public key.
-A secp256k1-based ECDSA signature.
-
-struct Signature has copy, drop, store
+struct ECDSACompressedPublicKey has copy, drop, store
-
-Fields
+##### Fields
@@ -80,308 +77,339 @@ A secp256k1-based ECDSA signature.
-
+
-
+## Struct `ECDSASignature`
-## Constants
+A 64-byte ECDSA signature.
-
+struct ECDSASignature has copy, drop, store
+
-Wrong number of bytes were given as pubkey.
-const E_WRONG_PUBKEY_SIZE: u64 = 1;
-
+##### Fields
+
+-
+
bytes: vector<u8>
+
+-
-
+
+
-Wrong number of bytes were given as signature.
+
+
+## Constants
+
+
+
+
+The size of a secp256k1-based ECDSA compressed public key, in bytes.
-const E_WRONG_SIGNATURE_SIZE: u64 = 2;
+
+const COMPRESSED_PUBLIC_KEY_SIZE: u64 = 33;
-
+
-The size of a secp256k1-based ECDSA compressed-public key, in bytes.
+An error occurred while deserializing, for example due to wrong input size.
-const PUBLIC_KEY_SIZE: u64 = 33;
+const E_DESERIALIZE: u64 = 1;
-
+
-The size of a secp256k1-based ECDSA signature, in bytes.
+The size of a hashed message for secp256k1-based ECDSA signing
-const SIGNATURE_SIZE: u64 = 64;
+const MESSAGE_SIZE: u64 = 32;
-
+
-Wrong number of bytes were given as message.
+The size of a secp256k1-based ECDSA public key, in bytes.
-const E_WRONG_MESSAGE_SIZE: u64 = 2;
+const RAW_PUBLIC_KEY_NUM_BYTES: u64 = 64;
-
+
-The size of a hashed message for secp256k1-based ECDSA signing
+The size of a secp256k1-based ECDSA signature, in bytes.
-const MESSAGE_SIZE: u64 = 32;
+const SIGNATURE_NUM_BYTES: u64 = 64;
-
+
-## Function `public_key_from_bytes`
+## Function `ecdsa_signature_from_bytes`
-Constructs an PublicKey struct, given 33-byte representation.
+Constructs an ECDSASignature struct from the given 64 bytes.
-public fun public_key_from_bytes(bytes: vector<u8>): secp256k1::PublicKey
+public fun ecdsa_signature_from_bytes(bytes: vector<u8>): secp256k1::ECDSASignature
-
-Implementation
+##### Implementation
-public fun public_key_from_bytes(bytes: vector<u8>): PublicKey {
+public fun ecdsa_signature_from_bytes(bytes: vector<u8>): ECDSASignature {
assert!(
- std::vector::length(&bytes) == PUBLIC_KEY_SIZE,
- std::error::invalid_argument(PUBLIC_KEY_SIZE),
+ std::vector::length(&bytes) == SIGNATURE_NUM_BYTES,
+ std::error::invalid_argument(E_DESERIALIZE)
);
- PublicKey { bytes }
+ ECDSASignature { bytes }
}
-
-
-
+
-## Function `signature_from_bytes`
+## Function `ecdsa_raw_public_key_from_64_bytes`
-Constructs an Signature struct from the given 64 bytes.
+Constructs an ECDSARawPublicKey struct, given a 64-byte raw representation.
-public fun signature_from_bytes(bytes: vector<u8>): secp256k1::Signature
+public fun ecdsa_raw_public_key_from_64_bytes(bytes: vector<u8>): secp256k1::ECDSARawPublicKey
-
-Implementation
+##### Implementation
-public fun signature_from_bytes(bytes: vector<u8>): Signature {
- assert!(std::vector::length(&bytes) == SIGNATURE_SIZE, std::error::invalid_argument(E_WRONG_SIGNATURE_SIZE));
- Signature { bytes }
+public fun ecdsa_raw_public_key_from_64_bytes(bytes: vector<u8>): ECDSARawPublicKey {
+ ecdsa_raw_public_key_from_bytes(bytes)
}
-
-
-
+
-## Function `public_key_to_bytes`
+## Function `ecdsa_raw_public_key_from_bytes`
-Serializes an PublicKey struct to bytes.
+Constructs an ECDSARawPublicKey struct, given a 64-byte raw representation.
-public fun public_key_to_bytes(pk: &secp256k1::PublicKey): vector<u8>
+public fun ecdsa_raw_public_key_from_bytes(bytes: vector<u8>): secp256k1::ECDSARawPublicKey
-
-Implementation
+##### Implementation
-public fun public_key_to_bytes(pk: &PublicKey): vector<u8> {
- pk.bytes
+public fun ecdsa_raw_public_key_from_bytes(bytes: vector<u8>): ECDSARawPublicKey {
+ assert!(
+ std::vector::length(&bytes) == RAW_PUBLIC_KEY_NUM_BYTES,
+ std::error::invalid_argument(E_DESERIALIZE)
+ );
+ ECDSARawPublicKey { bytes }
}
-
+
-
+## Function `ecdsa_compressed_public_key_from_bytes`
-## Function `signature_to_bytes`
+Constructs an ECDSACompressedPublicKey struct, given a 33-byte raw representation.
-Serializes an Signature struct to bytes.
-
-public fun signature_to_bytes(sig: &secp256k1::Signature): vector<u8>
+public fun ecdsa_compressed_public_key_from_bytes(bytes: vector<u8>): secp256k1::ECDSACompressedPublicKey
-
-Implementation
+##### Implementation
-public fun signature_to_bytes(sig: &Signature): vector<u8> {
- sig.bytes
+public fun ecdsa_compressed_public_key_from_bytes(bytes: vector<u8>):
+ ECDSACompressedPublicKey {
+ assert!(
+ std::vector::length(&bytes) == COMPRESSED_PUBLIC_KEY_SIZE,
+ std::error::invalid_argument(E_DESERIALIZE)
+ );
+ ECDSACompressedPublicKey { bytes }
}
-
-
-
+
-## Function `verify`
+## Function `ecdsa_raw_public_key_to_bytes`
-Returns true
only the signature can verify the public key on the message
+Serializes an ECDSARawPublicKey struct to 64-bytes.
-public fun verify(message: vector<u8>, public_key: &secp256k1::PublicKey, signature: &secp256k1::Signature): bool
+public fun ecdsa_raw_public_key_to_bytes(pk: &secp256k1::ECDSARawPublicKey): vector<u8>
-
-Implementation
+##### Implementation
-public fun verify(
- message: vector<u8>,
- public_key: &PublicKey,
- signature: &Signature,
-): bool {
- assert!(
- std::vector::length(&message) == MESSAGE_SIZE,
- std::error::invalid_argument(E_WRONG_MESSAGE_SIZE),
- );
-
- return verify_internal(message, public_key.bytes, signature.bytes)
+public fun ecdsa_raw_public_key_to_bytes(pk: &ECDSARawPublicKey): vector<u8> {
+ pk.bytes
}
-
+
-
+## Function `ecdsa_compressed_public_key_to_bytes`
-## Function `recover_public_key`
+Serializes an ECDSARawPublicKey struct to 64-bytes.
+
+
+public fun ecdsa_compressed_public_key_to_bytes(pk: &secp256k1::ECDSACompressedPublicKey): vector<u8>
+
-Recovers the signer's (33-byte) compressed public key from a secp256k1 ECDSA signature
given the recovery_id
-and the signed message
(32 byte digest).
-Note that an invalid signature, or a signature from a different message, will result in the recovery of an
-incorrect public key. This recovery algorithm can only be used to check validity of a signature if the signer's
-public key (or its hash) is known beforehand.
+##### Implementation
-public fun recover_public_key(message: vector<u8>, recovery_id: u8, signature: &secp256k1::Signature): option::Option<secp256k1::PublicKey>
+
+public fun ecdsa_compressed_public_key_to_bytes(
+ pk: &ECDSACompressedPublicKey
+): vector<u8> {
+ pk.bytes
+}
-
-Implementation
+
+## Function `ecdsa_signature_to_bytes`
-public fun recover_public_key(
- message: vector<u8>,
- recovery_id: u8,
- signature: &Signature,
-): Option<PublicKey> {
- assert!(
- std::vector::length(&message) == MESSAGE_SIZE,
- std::error::invalid_argument(E_WRONG_MESSAGE_SIZE),
- );
+Serializes an ECDSASignature struct to 64-bytes.
- let (pk, success) = recover_public_key_internal(recovery_id, message, signature.bytes);
- if (success) {
- std::option::some(public_key_from_bytes(pk))
- } else {
- std::option::none<PublicKey>()
- }
-}
+
+public fun ecdsa_signature_to_bytes(sig: &secp256k1::ECDSASignature): vector<u8>
-
+##### Implementation
-
-## Function `verify_internal`
+public fun ecdsa_signature_to_bytes(sig: &ECDSASignature): vector<u8> {
+ sig.bytes
+}
+
-Returns true
if signature
verifies on public_key
and message
-and returns false
otherwise.
-fun verify_internal(message: vector<u8>, public_key: vector<u8>, signature: vector<u8>): bool
-
+
+## Function `ecdsa_recover`
+Recovers the signer's raw (64-byte) public key from a secp256k1 ECDSA signature
given the recovery_id
and the signed
+message
(32 byte digest).
-
-Implementation
+Note that an invalid signature, or a signature from a different message, will result in the recovery of an
+incorrect public key. This recovery algorithm can only be used to check validity of a signature if the signer's
+public key (or its hash) is known beforehand.
-native fun verify_internal(
- message: vector<u8>,
- public_key: vector<u8>,
- signature: vector<u8>,
-): bool;
+public fun ecdsa_recover(message: vector<u8>, recovery_id: u8, signature: &secp256k1::ECDSASignature): option::Option<secp256k1::ECDSARawPublicKey>
-
+##### Implementation
-
-## Function `recover_public_key_internal`
+public fun ecdsa_recover(
+ message: vector<u8>, recovery_id: u8, signature: &ECDSASignature
+): Option<ECDSARawPublicKey> {
+ assert!(
+ std::vector::length(&message) == MESSAGE_SIZE,
+ std::error::invalid_argument(E_DESERIALIZE)
+ );
-Returns (public_key, true)
if signature
verifies on message
under the recovered public_key
-and returns ([], false)
otherwise.
+ let (pk, success) =
+ recover_public_key_internal(
+ recovery_id,
+ message,
+ signature.bytes,
+ false
+ );
+ if (success) {
+ std::option::some(ecdsa_raw_public_key_from_bytes(pk))
+ } else {
+ std::option::none<ECDSARawPublicKey>()
+ }
+}
+
-fun recover_public_key_internal(recovery_id: u8, message: vector<u8>, signature: vector<u8>): (vector<u8>, bool)
-
+
+
+## Function `ecdsa_recover_compressed`
+Recovers the signer's raw (64-byte) public key from a secp256k1 ECDSA signature
given the recovery_id
and the signed
+message
(32 byte digest).
-
-Implementation
+Note that an invalid signature, or a signature from a different message, will result in the recovery of an
+incorrect public key. This recovery algorithm can only be used to check validity of a signature if the signer's
+public key (or its hash) is known beforehand.
-native fun recover_public_key_internal(
- recovery_id: u8,
- message: vector<u8>,
- signature: vector<u8>,
-): (vector<u8>, bool);
+public fun ecdsa_recover_compressed(message: vector<u8>, recovery_id: u8, signature: &secp256k1::ECDSASignature): option::Option<secp256k1::ECDSACompressedPublicKey>
-
+##### Implementation
+
+
+public fun ecdsa_recover_compressed(
+ message: vector<u8>, recovery_id: u8, signature: &ECDSASignature
+): Option<ECDSACompressedPublicKey> {
+ assert!(
+ std::vector::length(&message) == MESSAGE_SIZE,
+ std::error::invalid_argument(E_DESERIALIZE)
+ );
+
+ let (pk, success) =
+ recover_public_key_internal(
+ recovery_id,
+ message,
+ signature.bytes,
+ true
+ );
+ if (success) {
+ std::option::some(ecdsa_compressed_public_key_from_bytes(pk))
+ } else {
+ std::option::none<ECDSACompressedPublicKey>()
+ }
+}
+
diff --git a/initia_stdlib/doc/simple_json.md b/initia_stdlib/doc/simple_json.md
deleted file mode 100644
index 23dd20e..0000000
--- a/initia_stdlib/doc/simple_json.md
+++ /dev/null
@@ -1,635 +0,0 @@
-
-
-
-# Module `0x1::simple_json`
-
-simple_json is a serde style json wrapper to build objects easier
-
-
-- [Struct `SimpleJsonObject`](#0x1_simple_json_SimpleJsonObject)
-- [Constants](#@Constants_0)
-- [Function `empty`](#0x1_simple_json_empty)
-- [Function `from_json_object`](#0x1_simple_json_from_json_object)
-- [Function `to_json_object`](#0x1_simple_json_to_json_object)
-- [Function `index`](#0x1_simple_json_index)
-- [Function `increase_depth`](#0x1_simple_json_increase_depth)
-- [Function `decrease_depth`](#0x1_simple_json_decrease_depth)
-- [Function `set_index_internal`](#0x1_simple_json_set_index_internal)
-- [Function `set_child_length`](#0x1_simple_json_set_child_length)
-- [Function `borrow`](#0x1_simple_json_borrow)
-- [Function `borrow_mut`](#0x1_simple_json_borrow_mut)
-- [Function `set_index`](#0x1_simple_json_set_index)
-- [Function `set_to_last_index`](#0x1_simple_json_set_to_last_index)
-- [Function `find_and_set_index`](#0x1_simple_json_find_and_set_index)
-- [Function `try_find_and_set_index`](#0x1_simple_json_try_find_and_set_index)
-- [Function `set_bool`](#0x1_simple_json_set_bool)
-- [Function `set_int_raw`](#0x1_simple_json_set_int_raw)
-- [Function `set_int_string`](#0x1_simple_json_set_int_string)
-- [Function `set_dec_string`](#0x1_simple_json_set_dec_string)
-- [Function `set_string`](#0x1_simple_json_set_string)
-- [Function `set_array`](#0x1_simple_json_set_array)
-- [Function `set_object`](#0x1_simple_json_set_object)
-
-
-use 0x1::decimal256;
-use 0x1::json;
-use 0x1::option;
-use 0x1::string;
-
-
-
-
-
-
-## Struct `SimpleJsonObject`
-
-
-
-struct SimpleJsonObject has copy, drop
-
-
-
-
-
-Fields
-
-
-
--
-
obj: json::JsonObject
-
--
-
-
--
-
index: json::JsonIndex
-
--
-
-
-
-
-
-
-
-
-
-## Constants
-
-
-
-
-
-
-const EKEY_NOT_FOUND: u64 = 0;
-
-
-
-
-
-
-## Function `empty`
-
-
-
-public fun empty(): simple_json::SimpleJsonObject
-
-
-
-
-
-Implementation
-
-
-public fun empty(): SimpleJsonObject{
- SimpleJsonObject {
- obj: json::empty(),
- index: json::start_index(),
- }
-}
-
-
-
-
-
-
-
-
-## Function `from_json_object`
-
-
-
-public fun from_json_object(object: json::JsonObject): simple_json::SimpleJsonObject
-
-
-
-
-
-Implementation
-
-
-public fun from_json_object(object: JsonObject): SimpleJsonObject{
- SimpleJsonObject {
- obj: object,
- index: json::start_index(),
- }
-}
-
-
-
-
-
-
-
-
-## Function `to_json_object`
-
-
-
-public fun to_json_object(object: &simple_json::SimpleJsonObject): &json::JsonObject
-
-
-
-
-
-Implementation
-
-
-public fun to_json_object(object: &SimpleJsonObject): &JsonObject{
- &object.obj
-}
-
-
-
-
-
-
-
-
-## Function `index`
-
-
-
-public fun index(object: &simple_json::SimpleJsonObject): &json::JsonIndex
-
-
-
-
-
-Implementation
-
-
-public fun index(object: &SimpleJsonObject): &JsonIndex{
- &object.index
-}
-
-
-
-
-
-
-
-
-## Function `increase_depth`
-
-
-
-public fun increase_depth(object: &mut simple_json::SimpleJsonObject)
-
-
-
-
-
-Implementation
-
-
-public fun increase_depth(object: &mut SimpleJsonObject) {
- object.index = json::get_next_index(&object.index, 0)
-}
-
-
-
-
-
-
-
-
-## Function `decrease_depth`
-
-
-
-public fun decrease_depth(object: &mut simple_json::SimpleJsonObject)
-
-
-
-
-
-Implementation
-
-
-public fun decrease_depth(object: &mut SimpleJsonObject) {
- let (prev_index, _) = json::get_prev_index(&object.index);
- object.index = prev_index;
-}
-
-
-
-
-
-
-
-
-## Function `set_index_internal`
-
-
-
-fun set_index_internal(object: &mut simple_json::SimpleJsonObject): u64
-
-
-
-
-
-Implementation
-
-
-fun set_index_internal(object: &mut SimpleJsonObject): u64{
- if(json::get_depth(&object.index) == 1) return 0;
-
- let (prev_index, last) = json::get_prev_index(&object.index);
-
- if(last == 0 && json::get_child_length(json::borrow(&object.obj, &prev_index)) == 0) return 0;
- object.index = json::get_next_index(&prev_index, last + 1);
- last+1
-}
-
-
-
-
-
-
-
-
-## Function `set_child_length`
-
-
-
-fun set_child_length(object: &mut simple_json::SimpleJsonObject)
-
-
-
-
-
-Implementation
-
-
-fun set_child_length(object: &mut SimpleJsonObject) {
- let (prev_index, last) = json::get_prev_index(&object.index);
- json::set_child_length(json::borrow_mut(&mut object.obj, &prev_index) ,last+1);
-}
-
-
-
-
-
-
-
-
-## Function `borrow`
-
-
-
-public fun borrow(object: &simple_json::SimpleJsonObject): &json::JsonElem
-
-
-
-
-
-Implementation
-
-
-public fun borrow(object: &SimpleJsonObject): &JsonElem {
- json::borrow(&object.obj, &object.index)
-}
-
-
-
-
-
-
-
-
-## Function `borrow_mut`
-
-
-
-public fun borrow_mut(object: &mut simple_json::SimpleJsonObject): &mut json::JsonElem
-
-
-
-
-
-Implementation
-
-
-public fun borrow_mut(object: &mut SimpleJsonObject): &mut JsonElem {
- json::borrow_mut(&mut object.obj, &object.index)
-}
-
-
-
-
-
-
-
-
-## Function `set_index`
-
-
-
-public fun set_index(object: &mut simple_json::SimpleJsonObject, position: u64)
-
-
-
-
-
-Implementation
-
-
-public fun set_index(object: &mut SimpleJsonObject, position: u64){
- let (prev_index, _) = json::get_prev_index(&object.index);
- object.index = json::get_next_index(&prev_index, position);
-}
-
-
-
-
-
-
-
-
-## Function `set_to_last_index`
-
-
-
-public fun set_to_last_index(object: &mut simple_json::SimpleJsonObject)
-
-
-
-
-
-Implementation
-
-
-public fun set_to_last_index(object: &mut SimpleJsonObject){
- let (prev_index, _) = json::get_prev_index(&object.index);
- let child_length = json::get_child_length(json::borrow(&object.obj, &prev_index));
- if(child_length == 0) return;
- object.index = json::get_next_index(&prev_index, child_length - 1);
-}
-
-
-
-
-
-
-
-
-## Function `find_and_set_index`
-
-
-
-public fun find_and_set_index(object: &mut simple_json::SimpleJsonObject, key: &string::String)
-
-
-
-
-
-Implementation
-
-
-public fun find_and_set_index(object: &mut SimpleJsonObject, key: &String) {
- let (prev_index, _) = json::get_prev_index(&object.index);
- let find_index = json::find(&object.obj, &prev_index, key);
-
- assert!(!json::is_null_index(&find_index), EKEY_NOT_FOUND);
- object.index = find_index;
-}
-
-
-
-
-
-
-
-
-## Function `try_find_and_set_index`
-
-
-
-public fun try_find_and_set_index(object: &mut simple_json::SimpleJsonObject, key: &string::String): bool
-
-
-
-
-
-Implementation
-
-
-public fun try_find_and_set_index(object: &mut SimpleJsonObject, key: &String):bool {
- let (prev_index, _) = json::get_prev_index(&object.index);
- let find_index = json::find(&object.obj, &prev_index, key);
-
- if ( json::is_null_index(&find_index)) {
- false
- } else {
- object.index = find_index;
- true
- }
-}
-
-
-
-
-
-
-
-
-## Function `set_bool`
-
-
-
-public fun set_bool(object: &mut simple_json::SimpleJsonObject, key: option::Option<string::String>, value: bool)
-
-
-
-
-
-Implementation
-
-
-public fun set_bool(object: &mut SimpleJsonObject, key: Option<String>, value: bool) {
- set_index_internal(object);
- json::set_bool(&mut object.obj, object.index, key, value);
- if(json::get_depth(&object.index) != 1) set_child_length(object);
-}
-
-
-
-
-
-
-
-
-## Function `set_int_raw`
-
-
-
-public fun set_int_raw(object: &mut simple_json::SimpleJsonObject, key: option::Option<string::String>, is_positive: bool, value: u256)
-
-
-
-
-
-Implementation
-
-
-public fun set_int_raw(object:&mut SimpleJsonObject, key: Option<String>, is_positive: bool, value: u256) {
- set_index_internal(object);
- json::set_int_raw(&mut object.obj, object.index, key, is_positive, value);
- if(json::get_depth(&object.index) != 1) set_child_length(object);
-}
-
-
-
-
-
-
-
-
-## Function `set_int_string`
-
-
-
-public fun set_int_string(object: &mut simple_json::SimpleJsonObject, key: option::Option<string::String>, is_positive: bool, value: u256)
-
-
-
-
-
-Implementation
-
-
-public fun set_int_string(object:&mut SimpleJsonObject, key: Option<String>, is_positive: bool, value: u256) {
- set_index_internal(object);
- json::set_int_string(&mut object.obj, object.index, key, is_positive, value);
- if(json::get_depth(&object.index) != 1) set_child_length(object);
-}
-
-
-
-
-
-
-
-
-## Function `set_dec_string`
-
-
-
-public fun set_dec_string(object: &mut simple_json::SimpleJsonObject, key: option::Option<string::String>, is_positive: bool, value: decimal256::Decimal256)
-
-
-
-
-
-Implementation
-
-
-public fun set_dec_string(object:&mut SimpleJsonObject, key: Option<String>, is_positive: bool, value: Decimal256) {
- set_index_internal(object);
- json::set_dec_string(&mut object.obj, object.index, key, is_positive, value);
- if(json::get_depth(&object.index) != 1) set_child_length(object);
-}
-
-
-
-
-
-
-
-
-## Function `set_string`
-
-
-
-public fun set_string(object: &mut simple_json::SimpleJsonObject, key: option::Option<string::String>, value: string::String)
-
-
-
-
-
-Implementation
-
-
-public fun set_string(object: &mut SimpleJsonObject, key: Option<String>, value: String) {
- set_index_internal(object);
- json::set_string(&mut object.obj, object.index, key, value);
- if(json::get_depth(&object.index) != 1) set_child_length(object);
-}
-
-
-
-
-
-
-
-
-## Function `set_array`
-
-
-
-public fun set_array(object: &mut simple_json::SimpleJsonObject, key: option::Option<string::String>)
-
-
-
-
-
-Implementation
-
-
-public fun set_array(object: &mut SimpleJsonObject, key: Option<String>) {
- set_index_internal(object);
- json::set_array(&mut object.obj, object.index, key, 0);
- if(json::get_depth(&object.index) != 1) set_child_length(object);
-}
-
-
-
-
-
-
-
-
-## Function `set_object`
-
-
-
-public fun set_object(object: &mut simple_json::SimpleJsonObject, key: option::Option<string::String>)
-
-
-
-
-
-Implementation
-
-
-public fun set_object(object: &mut SimpleJsonObject, key: Option<String>) {
- set_index_internal(object);
- json::set_object(&mut object.obj, object.index, key, 0);
- if(json::get_depth(&object.index) != 1) set_child_length(object);
-}
-
-
-
-
-
diff --git a/initia_stdlib/doc/simple_map.md b/initia_stdlib/doc/simple_map.md
index d2f6b71..d3a714b 100644
--- a/initia_stdlib/doc/simple_map.md
+++ b/initia_stdlib/doc/simple_map.md
@@ -3,11 +3,11 @@
# Module `0x1::simple_map`
-This module provides a solution for sorted maps, that is it has the properties that
+This module provides a solution for unsorted maps, that is it has the properties that
1) Keys point to Values
2) Each Key must be unique
-3) A Key can be found within O(Log N) time
-4) The data is stored as a sorted by Key
+3) A Key can be found within O(N) time
+4) The keys are unsorted.
5) Adds and removals take O(N) time
@@ -15,19 +15,26 @@ This module provides a solution for sorted maps, that is it has the properties t
- [Struct `Element`](#0x1_simple_map_Element)
- [Constants](#@Constants_0)
- [Function `length`](#0x1_simple_map_length)
+- [Function `new`](#0x1_simple_map_new)
+- [Function `new_from`](#0x1_simple_map_new_from)
- [Function `create`](#0x1_simple_map_create)
- [Function `borrow`](#0x1_simple_map_borrow)
- [Function `borrow_mut`](#0x1_simple_map_borrow_mut)
- [Function `contains_key`](#0x1_simple_map_contains_key)
- [Function `destroy_empty`](#0x1_simple_map_destroy_empty)
- [Function `add`](#0x1_simple_map_add)
+- [Function `add_all`](#0x1_simple_map_add_all)
+- [Function `upsert`](#0x1_simple_map_upsert)
+- [Function `keys`](#0x1_simple_map_keys)
+- [Function `values`](#0x1_simple_map_values)
+- [Function `to_vec_pair`](#0x1_simple_map_to_vec_pair)
+- [Function `destroy`](#0x1_simple_map_destroy)
- [Function `remove`](#0x1_simple_map_remove)
-- [Function `find`](#0x1_simple_map_find)
-use 0x1::comparator;
-use 0x1::error;
+use 0x1::error;
use 0x1::option;
+use 0x1::vector;
@@ -43,8 +50,7 @@ This module provides a solution for sorted maps, that is it has the properties t
-
-Fields
+##### Fields
@@ -57,8 +63,6 @@ This module provides a solution for sorted maps, that is it has the properties t
-
-
## Struct `Element`
@@ -70,8 +74,7 @@ This module provides a solution for sorted maps, that is it has the properties t
-
-Fields
+##### Fields
@@ -90,8 +93,6 @@ This module provides a solution for sorted maps, that is it has the properties t
-
-
## Constants
@@ -99,18 +100,20 @@ This module provides a solution for sorted maps, that is it has the properties t
+Map key already exists
-const EKEY_ALREADY_EXISTS: u64 = 0;
+const EKEY_ALREADY_EXISTS: u64 = 1;
+Map key is not found
-const EKEY_NOT_FOUND: u64 = 1;
+const EKEY_NOT_FOUND: u64 = 2;
@@ -121,287 +124,437 @@ This module provides a solution for sorted maps, that is it has the properties t
-public fun length<Key: store, Value: store>(map: &simple_map::SimpleMap<Key, Value>): u64
+public fun length<Key: store, Value: store>(self: &simple_map::SimpleMap<Key, Value>): u64
-
-Implementation
+##### Implementation
-public fun length<Key: store, Value: store>(map: &SimpleMap<Key, Value>): u64 {
- vector::length(&map.data)
+public fun length<Key: store, Value: store>(self: &SimpleMap<Key, Value>): u64 {
+ vector::length(&self.data)
}
-
+
+
+## Function `new`
+
+Create an empty SimpleMap.
+
+
+public fun new<Key: store, Value: store>(): simple_map::SimpleMap<Key, Value>
+
+
+
+
+##### Implementation
+
+
+public fun new<Key: store, Value: store>(): SimpleMap<Key, Value> {
+ SimpleMap { data: vector::empty() }
+}
+
+
+
+
+
+
+## Function `new_from`
+
+Create a SimpleMap from a vector of keys and values. The keys must be unique.
+
+
+public fun new_from<Key: store, Value: store>(keys: vector<Key>, values: vector<Value>): simple_map::SimpleMap<Key, Value>
+
+
+
+
+##### Implementation
+
+
+public fun new_from<Key: store, Value: store>(
+ keys: vector<Key>, values: vector<Value>
+): SimpleMap<Key, Value> {
+ let map = new();
+ add_all(&mut map, keys, values);
+ map
+}
+
+
+
## Function `create`
+Create an empty SimpleMap.
+This function is deprecated, use new
instead.
-public fun create<Key: store, Value: store>(): simple_map::SimpleMap<Key, Value>
+#[deprecated]
+public fun create<Key: store, Value: store>(): simple_map::SimpleMap<Key, Value>
-
-Implementation
+##### Implementation
public fun create<Key: store, Value: store>(): SimpleMap<Key, Value> {
- SimpleMap {
- data: vector::empty(),
- }
+ new()
}
-
-
## Function `borrow`
-public fun borrow<Key: store, Value: store>(map: &simple_map::SimpleMap<Key, Value>, key: &Key): &Value
+public fun borrow<Key: store, Value: store>(self: &simple_map::SimpleMap<Key, Value>, key: &Key): &Value
-
-Implementation
+##### Implementation
public fun borrow<Key: store, Value: store>(
- map: &SimpleMap<Key, Value>,
- key: &Key,
+ self: &SimpleMap<Key, Value>, key: &Key
): &Value {
- let (maybe_idx, _) = find(map, key);
+ let maybe_idx = find(self, key);
assert!(option::is_some(&maybe_idx), error::invalid_argument(EKEY_NOT_FOUND));
let idx = option::extract(&mut maybe_idx);
- &vector::borrow(&map.data, idx).value
+ &vector::borrow(&self.data, idx).value
}
-
-
## Function `borrow_mut`
-public fun borrow_mut<Key: store, Value: store>(map: &mut simple_map::SimpleMap<Key, Value>, key: &Key): &mut Value
+public fun borrow_mut<Key: store, Value: store>(self: &mut simple_map::SimpleMap<Key, Value>, key: &Key): &mut Value
-
-Implementation
+##### Implementation
public fun borrow_mut<Key: store, Value: store>(
- map: &mut SimpleMap<Key, Value>,
- key: &Key,
+ self: &mut SimpleMap<Key, Value>, key: &Key
): &mut Value {
- let (maybe_idx, _) = find(map, key);
+ let maybe_idx = find(self, key);
assert!(option::is_some(&maybe_idx), error::invalid_argument(EKEY_NOT_FOUND));
let idx = option::extract(&mut maybe_idx);
- &mut vector::borrow_mut(&mut map.data, idx).value
+ &mut vector::borrow_mut(&mut self.data, idx).value
}
-
-
## Function `contains_key`
-public fun contains_key<Key: store, Value: store>(map: &simple_map::SimpleMap<Key, Value>, key: &Key): bool
+public fun contains_key<Key: store, Value: store>(self: &simple_map::SimpleMap<Key, Value>, key: &Key): bool
-
-Implementation
+##### Implementation
public fun contains_key<Key: store, Value: store>(
- map: &SimpleMap<Key, Value>,
- key: &Key,
+ self: &SimpleMap<Key, Value>, key: &Key
): bool {
- let (maybe_idx, _) = find(map, key);
+ let maybe_idx = find(self, key);
option::is_some(&maybe_idx)
}
-
-
## Function `destroy_empty`
-public fun destroy_empty<Key: store, Value: store>(map: simple_map::SimpleMap<Key, Value>)
+public fun destroy_empty<Key: store, Value: store>(self: simple_map::SimpleMap<Key, Value>)
-
-Implementation
+##### Implementation
-public fun destroy_empty<Key: store, Value: store>(map: SimpleMap<Key, Value>) {
- let SimpleMap { data } = map;
+public fun destroy_empty<Key: store, Value: store>(
+ self: SimpleMap<Key, Value>
+) {
+ let SimpleMap { data } = self;
vector::destroy_empty(data);
}
-
-
## Function `add`
+Add a key/value pair to the map. The key must not already exist.
-public fun add<Key: store, Value: store>(map: &mut simple_map::SimpleMap<Key, Value>, key: Key, value: Value)
+public fun add<Key: store, Value: store>(self: &mut simple_map::SimpleMap<Key, Value>, key: Key, value: Value)
-
-Implementation
+##### Implementation
public fun add<Key: store, Value: store>(
- map: &mut SimpleMap<Key, Value>,
+ self: &mut SimpleMap<Key, Value>,
key: Key,
- value: Value,
+ value: Value
) {
- let (maybe_idx, maybe_placement) = find(map, &key);
+ let maybe_idx = find(self, &key);
assert!(option::is_none(&maybe_idx), error::invalid_argument(EKEY_ALREADY_EXISTS));
- // Append to the end and then swap elements until the list is ordered again
- vector::push_back(&mut map.data, Element { key, value });
+ vector::push_back(&mut self.data, Element { key, value });
+}
+
+
+
+
+
+
+## Function `add_all`
+
+Add multiple key/value pairs to the map. The keys must not already exist.
+
+
+public fun add_all<Key: store, Value: store>(self: &mut simple_map::SimpleMap<Key, Value>, keys: vector<Key>, values: vector<Value>)
+
+
+
+
+##### Implementation
+
+
+public fun add_all<Key: store, Value: store>(
+ self: &mut SimpleMap<Key, Value>,
+ keys: vector<Key>,
+ values: vector<Value>
+) {
+ vector::zip(
+ keys,
+ values,
+ |key, value| {
+ add(self, key, value);
+ }
+ );
+}
+
+
+
+
+
+
+## Function `upsert`
+
+Insert key/value pair or update an existing key to a new value
+
- let placement = option::extract(&mut maybe_placement);
- let end = vector::length(&map.data) - 1;
- while (placement < end) {
- vector::swap(&mut map.data, placement, end);
- placement = placement + 1;
+public fun upsert<Key: store, Value: store>(self: &mut simple_map::SimpleMap<Key, Value>, key: Key, value: Value): (option::Option<Key>, option::Option<Value>)
+
+
+
+
+##### Implementation
+
+
+public fun upsert<Key: store, Value: store>(
+ self: &mut SimpleMap<Key, Value>,
+ key: Key,
+ value: Value
+): (std::option::Option<Key>, std::option::Option<Value>) {
+ let data = &mut self.data;
+ let len = vector::length(data);
+ let i = 0;
+ while (i < len) {
+ let element = vector::borrow(data, i);
+ if (&element.key == &key) {
+ vector::push_back(data, Element { key, value });
+ vector::swap(data, i, len);
+ let Element { key, value } = vector::pop_back(data);
+ return (std::option::some(key), std::option::some(value))
+ };
+ i = i + 1;
};
+ vector::push_back(&mut self.data, Element { key, value });
+ (std::option::none(), std::option::none())
}
-
+
+
+## Function `keys`
+
+Return all keys in the map. This requires keys to be copyable.
+
+
+public fun keys<Key: copy, Value>(self: &simple_map::SimpleMap<Key, Value>): vector<Key>
+
-
-## Function `remove`
+##### Implementation
-public fun remove<Key: store, Value: store>(map: &mut simple_map::SimpleMap<Key, Value>, key: &Key): (Key, Value)
+public fun keys<Key: copy, Value>(self: &SimpleMap<Key, Value>): vector<Key> {
+ vector::map_ref(
+ &self.data,
+ |e| {
+ let e: &Element<Key, Value> = e;
+ e.key
+ }
+ )
+}
-
-Implementation
+
+## Function `values`
-public fun remove<Key: store, Value: store>(
- map: &mut SimpleMap<Key, Value>,
- key: &Key,
-): (Key, Value) {
- let (maybe_idx, _) = find(map, key);
- assert!(option::is_some(&maybe_idx), error::invalid_argument(EKEY_NOT_FOUND));
+Return all values in the map. This requires values to be copyable.
- let placement = option::extract(&mut maybe_idx);
- let end = vector::length(&map.data) - 1;
- while (placement < end) {
- vector::swap(&mut map.data, placement, placement + 1);
- placement = placement + 1;
- };
+public fun values<Key, Value: copy>(self: &simple_map::SimpleMap<Key, Value>): vector<Value>
+
- let Element { key, value } = vector::pop_back(&mut map.data);
- (key, value)
+
+
+##### Implementation
+
+
+public fun values<Key, Value: copy>(self: &SimpleMap<Key, Value>): vector<Value> {
+ vector::map_ref(
+ &self.data,
+ |e| {
+ let e: &Element<Key, Value> = e;
+ e.value
+ }
+ )
}
-
+
+
+## Function `to_vec_pair`
+
+Transform the map into two vectors with the keys and values respectively
+Primarily used to destroy a map
+
+
+public fun to_vec_pair<Key: store, Value: store>(self: simple_map::SimpleMap<Key, Value>): (vector<Key>, vector<Value>)
+
-
-## Function `find`
+##### Implementation
-fun find<Key: store, Value: store>(map: &simple_map::SimpleMap<Key, Value>, key: &Key): (option::Option<u64>, option::Option<u64>)
+public fun to_vec_pair<Key: store, Value: store>(
+ self: SimpleMap<Key, Value>
+): (vector<Key>, vector<Value>) {
+ let keys: vector<Key> = vector::empty();
+ let values: vector<Value> = vector::empty();
+ let SimpleMap { data } = self;
+ vector::for_each(
+ data,
+ |e| {
+ let Element { key, value } = e;
+ vector::push_back(&mut keys, key);
+ vector::push_back(&mut values, value);
+ }
+ );
+ (keys, values)
+}
-
-Implementation
+
+## Function `destroy`
-fun find<Key: store, Value: store>(
- map: &SimpleMap<Key, Value>,
- key: &Key,
-): (option::Option<u64>, option::Option<u64>) {
- let length = vector::length(&map.data);
+For maps that cannot be dropped this is a utility to destroy them
+using lambdas to destroy the individual keys and values.
- if (length == 0) {
- return (option::none(), option::some(0))
- };
- let left = 0;
- let right = length;
+public fun destroy<Key: store, Value: store>(self: simple_map::SimpleMap<Key, Value>, dk: |Key|, dv: |Value|)
+
+
- while (left != right) {
- let mid = (left + right) / 2;
- let potential_key = &vector::borrow(&map.data, mid).key;
- if (comparator::is_smaller_than(&comparator::compare(potential_key, key))) {
- left = mid + 1;
- } else {
- right = mid;
- };
- };
- if (left != length && key == &vector::borrow(&map.data, left).key) {
- (option::some(left), option::none())
- } else {
- (option::none(), option::some(left))
- }
+##### Implementation
+
+
+public inline fun destroy<Key: store, Value: store>(
+ self: SimpleMap<Key, Value>,
+ dk: |Key|,
+ dv: |Value|
+) {
+ let (keys, values) = to_vec_pair(self);
+ vector::destroy(keys, |_k| dk(_k));
+ vector::destroy(values, |_v| dv(_v));
}
-
+
+
+## Function `remove`
+
+Remove a key/value pair from the map. The key must exist.
+
+
+public fun remove<Key: store, Value: store>(self: &mut simple_map::SimpleMap<Key, Value>, key: &Key): (Key, Value)
+
+
+
+
+##### Implementation
+
+
+public fun remove<Key: store, Value: store>(
+ self: &mut SimpleMap<Key, Value>, key: &Key
+): (Key, Value) {
+ let maybe_idx = find(self, key);
+ assert!(option::is_some(&maybe_idx), error::invalid_argument(EKEY_NOT_FOUND));
+ let placement = option::extract(&mut maybe_idx);
+ let Element { key, value } = vector::swap_remove(&mut self.data, placement);
+ (key, value)
+}
+
diff --git a/initia_stdlib/doc/simple_nft.md b/initia_stdlib/doc/simple_nft.md
index 622539c..418409e 100644
--- a/initia_stdlib/doc/simple_nft.md
+++ b/initia_stdlib/doc/simple_nft.md
@@ -13,9 +13,7 @@ Sample of nft extension including metadata property type by using 0x1::initia_nf
- [Function `create_collection_object`](#0x1_simple_nft_create_collection_object)
- [Function `mint`](#0x1_simple_nft_mint)
- [Function `mint_nft_object`](#0x1_simple_nft_mint_nft_object)
-- [Function `borrow`](#0x1_simple_nft_borrow)
- [Function `are_properties_mutable`](#0x1_simple_nft_are_properties_mutable)
-- [Function `authorized_borrow`](#0x1_simple_nft_authorized_borrow)
- [Function `burn`](#0x1_simple_nft_burn)
- [Function `set_description`](#0x1_simple_nft_set_description)
- [Function `set_uri`](#0x1_simple_nft_set_uri)
@@ -24,23 +22,20 @@ Sample of nft extension including metadata property type by using 0x1::initia_nf
- [Function `remove_property`](#0x1_simple_nft_remove_property)
- [Function `update_property`](#0x1_simple_nft_update_property)
- [Function `update_typed_property`](#0x1_simple_nft_update_typed_property)
-- [Function `collection_object`](#0x1_simple_nft_collection_object)
-- [Function `borrow_collection`](#0x1_simple_nft_borrow_collection)
- [Function `is_mutable_collection_description`](#0x1_simple_nft_is_mutable_collection_description)
- [Function `is_mutable_collection_royalty`](#0x1_simple_nft_is_mutable_collection_royalty)
- [Function `is_mutable_collection_uri`](#0x1_simple_nft_is_mutable_collection_uri)
- [Function `is_mutable_collection_nft_description`](#0x1_simple_nft_is_mutable_collection_nft_description)
- [Function `is_mutable_collection_nft_uri`](#0x1_simple_nft_is_mutable_collection_nft_uri)
- [Function `is_mutable_collection_nft_properties`](#0x1_simple_nft_is_mutable_collection_nft_properties)
-- [Function `authorized_borrow_collection`](#0x1_simple_nft_authorized_borrow_collection)
- [Function `set_collection_description`](#0x1_simple_nft_set_collection_description)
- [Function `set_collection_royalties`](#0x1_simple_nft_set_collection_royalties)
- [Function `set_collection_royalties_call`](#0x1_simple_nft_set_collection_royalties_call)
- [Function `set_collection_uri`](#0x1_simple_nft_set_collection_uri)
-use 0x1::collection;
-use 0x1::decimal128;
+use 0x1::bigdecimal;
+use 0x1::collection;
use 0x1::error;
use 0x1::initia_nft;
use 0x1::nft;
@@ -66,8 +61,7 @@ Storage state for managing the no-code Collection.
-
-Fields
+##### Fields
@@ -80,8 +74,6 @@ Storage state for managing the no-code Collection.
-
-
## Resource `SimpleNft`
@@ -94,8 +86,7 @@ Storage state for managing the no-code Nft.
-
-Fields
+##### Fields
@@ -108,8 +99,6 @@ Storage state for managing the no-code Nft.
-
-
## Constants
@@ -172,13 +161,12 @@ The property map being mutated is not mutable
Create a new collection
-public entry fun create_collection(creator: &signer, description: string::String, max_supply: option::Option<u64>, name: string::String, uri: string::String, mutable_description: bool, mutable_royalty: bool, mutable_uri: bool, mutable_nft_description: bool, mutable_nft_properties: bool, mutable_nft_uri: bool, royalty: decimal128::Decimal128)
+public entry fun create_collection(creator: &signer, description: string::String, max_supply: option::Option<u64>, name: string::String, uri: string::String, mutable_description: bool, mutable_royalty: bool, mutable_uri: bool, mutable_nft_description: bool, mutable_nft_properties: bool, mutable_nft_uri: bool, royalty: bigdecimal::BigDecimal)
-
-Implementation
+##### Implementation
public entry fun create_collection(
@@ -193,7 +181,7 @@ Create a new collection
mutable_nft_description: bool,
mutable_nft_properties: bool,
mutable_nft_uri: bool,
- royalty: Decimal128,
+ royalty: BigDecimal
) {
create_collection_object(
creator,
@@ -207,28 +195,25 @@ Create a new collection
mutable_nft_description,
mutable_nft_properties,
mutable_nft_uri,
- royalty,
+ royalty
);
}
-
-
## Function `create_collection_object`
-public fun create_collection_object(creator: &signer, description: string::String, max_supply: option::Option<u64>, name: string::String, uri: string::String, mutable_description: bool, mutable_royalty: bool, mutable_uri: bool, mutable_nft_description: bool, mutable_nft_properties: bool, mutable_nft_uri: bool, royalty: decimal128::Decimal128): object::Object<simple_nft::SimpleNftCollection>
+public fun create_collection_object(creator: &signer, description: string::String, max_supply: option::Option<u64>, name: string::String, uri: string::String, mutable_description: bool, mutable_royalty: bool, mutable_uri: bool, mutable_nft_description: bool, mutable_nft_properties: bool, mutable_nft_uri: bool, royalty: bigdecimal::BigDecimal): object::Object<simple_nft::SimpleNftCollection>
-
-Implementation
+##### Implementation
public fun create_collection_object(
@@ -243,27 +228,26 @@ Create a new collection
mutable_nft_description: bool,
mutable_nft_properties: bool,
mutable_nft_uri: bool,
- royalty: Decimal128,
+ royalty: BigDecimal
): Object<SimpleNftCollection> {
- let (_, extend_ref) = initia_nft::create_collection_object(
- creator,
- description,
- max_supply,
- name,
- uri,
- mutable_description,
- mutable_royalty,
- mutable_uri,
- mutable_nft_description,
- mutable_nft_uri,
- royalty,
- );
+ let (_, extend_ref) =
+ initia_nft::create_collection_object(
+ creator,
+ description,
+ max_supply,
+ name,
+ uri,
+ mutable_description,
+ mutable_royalty,
+ mutable_uri,
+ mutable_nft_description,
+ mutable_nft_uri,
+ royalty
+ );
let object_signer = object::generate_signer_for_extending(&extend_ref);
- let simple_nft_collection = SimpleNftCollection {
- mutable_nft_properties,
- };
+ let simple_nft_collection = SimpleNftCollection { mutable_nft_properties };
move_to(&object_signer, simple_nft_collection);
object::address_to_object<SimpleNftCollection>(signer::address_of(&object_signer))
}
@@ -271,8 +255,6 @@ Create a new collection
-
-
## Function `mint`
@@ -285,8 +267,7 @@ With an existing collection, directly mint a viable nft into the creators accoun
-
-Implementation
+##### Implementation
public entry fun mint(
@@ -298,22 +279,31 @@ With an existing collection, directly mint a viable nft into the creators accoun
property_keys: vector<String>,
property_types: vector<String>,
property_values: vector<vector<u8>>,
- to: Option<address>,
+ to: Option<address>
) {
- let nft_object = mint_nft_object(
- creator, collection, description,
- token_id, uri, property_keys, property_types, property_values,
- );
+ let nft_object =
+ mint_nft_object(
+ creator,
+ collection,
+ description,
+ token_id,
+ uri,
+ property_keys,
+ property_types,
+ property_values
+ );
if (option::is_some(&to)) {
- object::transfer(creator, nft_object, option::extract(&mut to));
+ object::transfer(
+ creator,
+ nft_object,
+ option::extract(&mut to)
+ );
}
}
-
-
## Function `mint_nft_object`
@@ -326,8 +316,7 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-Implementation
+##### Implementation
public fun mint_nft_object(
@@ -338,23 +327,29 @@ Mint a nft into an existing collection, and retrieve the object / address of the
uri: String,
property_keys: vector<String>,
property_types: vector<String>,
- property_values: vector<vector<u8>>,
+ property_values: vector<vector<u8>>
): Object<SimpleNft> {
- let (object, extend_ref) = initia_nft::mint_nft_object(
- creator,
- collection,
- description,
- token_id,
- uri,
- true,
- );
+ let (object, extend_ref) =
+ initia_nft::mint_nft_object(
+ creator,
+ collection,
+ description,
+ token_id,
+ uri,
+ true
+ );
let s = object::generate_signer_for_extending(&extend_ref);
- let properties = property_map::prepare_input(property_keys, property_types, property_values);
+ let properties =
+ property_map::prepare_input(
+ property_keys,
+ property_types,
+ property_values
+ );
property_map::init(&s, properties);
let simple_nft = SimpleNft {
- property_mutator_ref: property_map::generate_mutator_ref(&s),
+ property_mutator_ref: property_map::generate_mutator_ref(&s)
};
move_to(&s, simple_nft);
@@ -364,37 +359,6 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-
-
-
-## Function `borrow`
-
-
-
-fun borrow<T: key>(nft: object::Object<T>): &simple_nft::SimpleNft
-
-
-
-
-
-Implementation
-
-
-inline fun borrow<T: key>(nft: Object<T>): &SimpleNft {
- let nft_address = object::object_address(nft);
- assert!(
- exists<SimpleNft>(nft_address),
- error::not_found(ENFT_DOES_NOT_EXIST),
- );
- borrow_global<SimpleNft>(nft_address)
-}
-
-
-
-
-
-
## Function `are_properties_mutable`
@@ -407,8 +371,7 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-Implementation
+##### Implementation
public fun are_properties_mutable<T: key>(nft: Object<T>): bool acquires SimpleNftCollection {
@@ -419,42 +382,6 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-
-
-
-## Function `authorized_borrow`
-
-
-
-fun authorized_borrow<T: key>(nft: object::Object<T>, creator: &signer): &simple_nft::SimpleNft
-
-
-
-
-
-Implementation
-
-
-inline fun authorized_borrow<T: key>(nft: Object<T>, creator: &signer): &SimpleNft {
- let nft_address = object::object_address(nft);
- assert!(
- exists<SimpleNft>(nft_address),
- error::not_found(ENFT_DOES_NOT_EXIST),
- );
-
- assert!(
- nft::creator(nft) == signer::address_of(creator),
- error::permission_denied(ENOT_CREATOR),
- );
- borrow_global<SimpleNft>(nft_address)
-}
-
-
-
-
-
-
## Function `burn`
@@ -466,22 +393,21 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-Implementation
+##### Implementation
public entry fun burn<T: key>(owner: &signer, nft: Object<T>) acquires SimpleNft {
- let nft_address = object::object_address(nft);
+ let nft_address = object::object_address(&nft);
assert!(
exists<SimpleNft>(nft_address),
- error::not_found(ENFT_DOES_NOT_EXIST),
+ error::not_found(ENFT_DOES_NOT_EXIST)
);
assert!(
object::owns(nft, signer::address_of(owner)),
- error::permission_denied(ENOT_OWNER),
+ error::permission_denied(ENOT_OWNER)
);
- let simple_nft = move_from<SimpleNft>(object::object_address(nft));
+ let simple_nft = move_from<SimpleNft>(object::object_address(&nft));
let SimpleNft { property_mutator_ref } = simple_nft;
property_map::burn(property_mutator_ref);
initia_nft::burn(owner, nft);
@@ -490,8 +416,6 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-
## Function `set_description`
@@ -503,14 +427,11 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-Implementation
+##### Implementation
public entry fun set_description<T: key>(
- creator: &signer,
- nft: Object<T>,
- description: String,
+ creator: &signer, nft: Object<T>, description: String
) {
initia_nft::set_description(creator, nft, description);
}
@@ -518,8 +439,6 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-
## Function `set_uri`
@@ -531,14 +450,11 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-Implementation
+##### Implementation
public entry fun set_uri<T: key>(
- creator: &signer,
- nft: Object<T>,
- uri: String,
+ creator: &signer, nft: Object<T>, uri: String
) {
initia_nft::set_uri(creator, nft, uri);
}
@@ -546,8 +462,6 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-
## Function `add_property`
@@ -559,8 +473,7 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-Implementation
+##### Implementation
public entry fun add_property<T: key>(
@@ -568,22 +481,25 @@ Mint a nft into an existing collection, and retrieve the object / address of the
nft: Object<T>,
key: String,
type: String,
- value: vector<u8>,
+ value: vector<u8>
) acquires SimpleNftCollection, SimpleNft {
let simple_nft = authorized_borrow(nft, creator);
assert!(
are_properties_mutable(nft),
- error::permission_denied(EPROPERTIES_NOT_MUTABLE),
+ error::permission_denied(EPROPERTIES_NOT_MUTABLE)
);
- property_map::add(&simple_nft.property_mutator_ref, key, type, value);
+ property_map::add(
+ &simple_nft.property_mutator_ref,
+ key,
+ type,
+ value
+ );
}
-
-
## Function `add_typed_property`
@@ -595,20 +511,19 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-Implementation
+##### Implementation
public entry fun add_typed_property<T: key, V: drop>(
creator: &signer,
nft: Object<T>,
key: String,
- value: V,
+ value: V
) acquires SimpleNftCollection, SimpleNft {
let simple_nft = authorized_borrow(nft, creator);
assert!(
are_properties_mutable(nft),
- error::permission_denied(EPROPERTIES_NOT_MUTABLE),
+ error::permission_denied(EPROPERTIES_NOT_MUTABLE)
);
property_map::add_typed(&simple_nft.property_mutator_ref, key, value);
@@ -617,8 +532,6 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-
## Function `remove_property`
@@ -630,19 +543,16 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-Implementation
+##### Implementation
public entry fun remove_property<T: key>(
- creator: &signer,
- nft: Object<T>,
- key: String,
+ creator: &signer, nft: Object<T>, key: String
) acquires SimpleNftCollection, SimpleNft {
let simple_nft = authorized_borrow(nft, creator);
assert!(
are_properties_mutable(nft),
- error::permission_denied(EPROPERTIES_NOT_MUTABLE),
+ error::permission_denied(EPROPERTIES_NOT_MUTABLE)
);
property_map::remove(&simple_nft.property_mutator_ref, &key);
@@ -651,8 +561,6 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-
## Function `update_property`
@@ -664,8 +572,7 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-Implementation
+##### Implementation
public entry fun update_property<T: key>(
@@ -673,22 +580,25 @@ Mint a nft into an existing collection, and retrieve the object / address of the
nft: Object<T>,
key: String,
type: String,
- value: vector<u8>,
+ value: vector<u8>
) acquires SimpleNftCollection, SimpleNft {
let simple_nft = authorized_borrow(nft, creator);
assert!(
are_properties_mutable(nft),
- error::permission_denied(EPROPERTIES_NOT_MUTABLE),
+ error::permission_denied(EPROPERTIES_NOT_MUTABLE)
);
- property_map::update(&simple_nft.property_mutator_ref, &key, type, value);
+ property_map::update(
+ &simple_nft.property_mutator_ref,
+ &key,
+ type,
+ value
+ );
}
-
-
## Function `update_typed_property`
@@ -700,84 +610,31 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-Implementation
+##### Implementation
public entry fun update_typed_property<T: key, V: drop>(
creator: &signer,
nft: Object<T>,
key: String,
- value: V,
+ value: V
) acquires SimpleNftCollection, SimpleNft {
let simple_nft = authorized_borrow(nft, creator);
assert!(
are_properties_mutable(nft),
- error::permission_denied(EPROPERTIES_NOT_MUTABLE),
+ error::permission_denied(EPROPERTIES_NOT_MUTABLE)
);
- property_map::update_typed(&simple_nft.property_mutator_ref, &key, value);
-}
-
-
-
-
-
-
-
-
-## Function `collection_object`
-
-
-
-fun collection_object(creator: &signer, name: &string::String): object::Object<simple_nft::SimpleNftCollection>
-
-
-
-
-
-Implementation
-
-
-inline fun collection_object(creator: &signer, name: &String): Object<SimpleNftCollection> {
- let collection_addr = collection::create_collection_address(signer::address_of(creator), name);
- object::address_to_object<SimpleNftCollection>(collection_addr)
-}
-
-
-
-
-
-
-
-
-## Function `borrow_collection`
-
-
-
-fun borrow_collection<T: key>(nft: object::Object<T>): &simple_nft::SimpleNftCollection
-
-
-
-
-
-Implementation
-
-
-inline fun borrow_collection<T: key>(nft: Object<T>): &SimpleNftCollection {
- let collection_address = object::object_address(nft);
- assert!(
- exists<SimpleNftCollection>(collection_address),
- error::not_found(ECOLLECTION_DOES_NOT_EXIST),
+ property_map::update_typed(
+ &simple_nft.property_mutator_ref,
+ &key,
+ value
);
- borrow_global<SimpleNftCollection>(collection_address)
}
-
-
## Function `is_mutable_collection_description`
@@ -789,12 +646,11 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-Implementation
+##### Implementation
public fun is_mutable_collection_description<T: key>(
- collection: Object<T>,
+ collection: Object<T>
): bool {
initia_nft::is_mutable_collection_description(collection)
}
@@ -802,8 +658,6 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-
## Function `is_mutable_collection_royalty`
@@ -815,12 +669,11 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-Implementation
+##### Implementation
public fun is_mutable_collection_royalty<T: key>(
- collection: Object<T>,
+ collection: Object<T>
): bool {
initia_nft::is_mutable_collection_royalty(collection)
}
@@ -828,8 +681,6 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-
## Function `is_mutable_collection_uri`
@@ -841,21 +692,16 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-Implementation
+##### Implementation
-public fun is_mutable_collection_uri<T: key>(
- collection: Object<T>,
-): bool {
+public fun is_mutable_collection_uri<T: key>(collection: Object<T>): bool {
initia_nft::is_mutable_collection_uri(collection)
}
-
-
## Function `is_mutable_collection_nft_description`
@@ -867,12 +713,11 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-Implementation
+##### Implementation
public fun is_mutable_collection_nft_description<T: key>(
- collection: Object<T>,
+ collection: Object<T>
): bool {
initia_nft::is_mutable_collection_nft_description(collection)
}
@@ -880,8 +725,6 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-
## Function `is_mutable_collection_nft_uri`
@@ -893,12 +736,11 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-Implementation
+##### Implementation
public fun is_mutable_collection_nft_uri<T: key>(
- collection: Object<T>,
+ collection: Object<T>
): bool {
initia_nft::is_mutable_collection_nft_uri(collection)
}
@@ -906,8 +748,6 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-
## Function `is_mutable_collection_nft_properties`
@@ -919,12 +759,11 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-Implementation
+##### Implementation
public fun is_mutable_collection_nft_properties<T: key>(
- collection: Object<T>,
+ collection: Object<T>
): bool acquires SimpleNftCollection {
borrow_collection(collection).mutable_nft_properties
}
@@ -932,41 +771,6 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-
-
-
-## Function `authorized_borrow_collection`
-
-
-
-fun authorized_borrow_collection<T: key>(collection: object::Object<T>, creator: &signer): &simple_nft::SimpleNftCollection
-
-
-
-
-
-Implementation
-
-
-inline fun authorized_borrow_collection<T: key>(collection: Object<T>, creator: &signer): &SimpleNftCollection {
- let collection_address = object::object_address(collection);
- assert!(
- exists<SimpleNftCollection>(collection_address),
- error::not_found(ECOLLECTION_DOES_NOT_EXIST),
- );
- assert!(
- collection::creator(collection) == signer::address_of(creator),
- error::permission_denied(ENOT_CREATOR),
- );
- borrow_global<SimpleNftCollection>(collection_address)
-}
-
-
-
-
-
-
## Function `set_collection_description`
@@ -978,14 +782,11 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-Implementation
+##### Implementation
public entry fun set_collection_description<T: key>(
- creator: &signer,
- collection: Object<T>,
- description: String,
+ creator: &signer, collection: Object<T>, description: String
) {
initia_nft::set_collection_description(creator, collection, description);
}
@@ -993,8 +794,6 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-
## Function `set_collection_royalties`
@@ -1006,14 +805,11 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-Implementation
+##### Implementation
public fun set_collection_royalties<T: key>(
- creator: &signer,
- collection: Object<T>,
- royalty: royalty::Royalty,
+ creator: &signer, collection: Object<T>, royalty: royalty::Royalty
) {
initia_nft::set_collection_royalties(creator, collection, royalty);
}
@@ -1021,28 +817,25 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-
## Function `set_collection_royalties_call`
-entry fun set_collection_royalties_call<T: key>(creator: &signer, collection: object::Object<T>, royalty: decimal128::Decimal128, payee_address: address)
+entry fun set_collection_royalties_call<T: key>(creator: &signer, collection: object::Object<T>, royalty: bigdecimal::BigDecimal, payee_address: address)
-
-Implementation
+##### Implementation
entry fun set_collection_royalties_call<T: key>(
creator: &signer,
collection: Object<T>,
- royalty: Decimal128,
- payee_address: address,
+ royalty: BigDecimal,
+ payee_address: address
) {
let royalty = royalty::create(royalty, payee_address);
set_collection_royalties(creator, collection, royalty);
@@ -1051,8 +844,6 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-
## Function `set_collection_uri`
@@ -1064,19 +855,12 @@ Mint a nft into an existing collection, and retrieve the object / address of the
-
-Implementation
+##### Implementation
public entry fun set_collection_uri<T: key>(
- creator: &signer,
- collection: Object<T>,
- uri: String,
+ creator: &signer, collection: Object<T>, uri: String
) {
initia_nft::set_collection_uri(creator, collection, uri);
}
-
-
-
-
diff --git a/initia_stdlib/doc/soul_bound_token.md b/initia_stdlib/doc/soul_bound_token.md
index 740c27b..c2d6cc8 100644
--- a/initia_stdlib/doc/soul_bound_token.md
+++ b/initia_stdlib/doc/soul_bound_token.md
@@ -14,13 +14,10 @@ initia_std::nft module.
- [Function `create_collection_object`](#0x1_soul_bound_token_create_collection_object)
- [Function `mint`](#0x1_soul_bound_token_mint)
- [Function `mint_soul_bound_token_object`](#0x1_soul_bound_token_mint_soul_bound_token_object)
-- [Function `mint_internal`](#0x1_soul_bound_token_mint_internal)
-- [Function `borrow`](#0x1_soul_bound_token_borrow)
- [Function `are_properties_mutable`](#0x1_soul_bound_token_are_properties_mutable)
- [Function `is_mutable_description`](#0x1_soul_bound_token_is_mutable_description)
- [Function `is_mutable_name`](#0x1_soul_bound_token_is_mutable_name)
- [Function `is_mutable_uri`](#0x1_soul_bound_token_is_mutable_uri)
-- [Function `authorized_borrow`](#0x1_soul_bound_token_authorized_borrow)
- [Function `set_description`](#0x1_soul_bound_token_set_description)
- [Function `set_uri`](#0x1_soul_bound_token_set_uri)
- [Function `add_property`](#0x1_soul_bound_token_add_property)
@@ -28,8 +25,6 @@ initia_std::nft module.
- [Function `remove_property`](#0x1_soul_bound_token_remove_property)
- [Function `update_property`](#0x1_soul_bound_token_update_property)
- [Function `update_typed_property`](#0x1_soul_bound_token_update_typed_property)
-- [Function `collection_object`](#0x1_soul_bound_token_collection_object)
-- [Function `borrow_collection`](#0x1_soul_bound_token_borrow_collection)
- [Function `is_mutable_collection_description`](#0x1_soul_bound_token_is_mutable_collection_description)
- [Function `is_mutable_collection_royalty`](#0x1_soul_bound_token_is_mutable_collection_royalty)
- [Function `is_mutable_collection_uri`](#0x1_soul_bound_token_is_mutable_collection_uri)
@@ -37,15 +32,14 @@ initia_std::nft module.
- [Function `is_mutable_collection_nft_name`](#0x1_soul_bound_token_is_mutable_collection_nft_name)
- [Function `is_mutable_collection_nft_uri`](#0x1_soul_bound_token_is_mutable_collection_nft_uri)
- [Function `is_mutable_collection_nft_properties`](#0x1_soul_bound_token_is_mutable_collection_nft_properties)
-- [Function `authorized_borrow_collection`](#0x1_soul_bound_token_authorized_borrow_collection)
- [Function `set_collection_description`](#0x1_soul_bound_token_set_collection_description)
- [Function `set_collection_royalties`](#0x1_soul_bound_token_set_collection_royalties)
- [Function `set_collection_royalties_call`](#0x1_soul_bound_token_set_collection_royalties_call)
- [Function `set_collection_uri`](#0x1_soul_bound_token_set_collection_uri)
-use 0x1::collection;
-use 0x1::decimal128;
+use 0x1::bigdecimal;
+use 0x1::collection;
use 0x1::error;
use 0x1::nft;
use 0x1::object;
@@ -70,8 +64,7 @@ Storage state for managing the no-code Collection.
-
-Fields
+##### Fields
@@ -126,8 +119,6 @@ Storage state for managing the no-code Collection.
-
-
## Resource `SoulBoundToken`
@@ -140,8 +131,7 @@ Storage state for managing the no-code Token.
-
-Fields
+##### Fields
@@ -160,8 +150,6 @@ Storage state for managing the no-code Token.
-
-
## Constants
@@ -224,13 +212,12 @@ The property map being mutated is not mutable
Create a new collection
-public entry fun create_collection(creator: &signer, description: string::String, max_supply: u64, name: string::String, uri: string::String, mutable_description: bool, mutable_royalty: bool, mutable_uri: bool, mutable_nft_description: bool, mutable_nft_name: bool, mutable_nft_properties: bool, mutable_nft_uri: bool, royalty: decimal128::Decimal128)
+public entry fun create_collection(creator: &signer, description: string::String, max_supply: u64, name: string::String, uri: string::String, mutable_description: bool, mutable_royalty: bool, mutable_uri: bool, mutable_nft_description: bool, mutable_nft_name: bool, mutable_nft_properties: bool, mutable_nft_uri: bool, royalty: bigdecimal::BigDecimal)
-
-Implementation
+##### Implementation
public entry fun create_collection(
@@ -246,7 +233,7 @@ Create a new collection
mutable_nft_name: bool,
mutable_nft_properties: bool,
mutable_nft_uri: bool,
- royalty: Decimal128,
+ royalty: BigDecimal
) {
create_collection_object(
creator,
@@ -261,28 +248,25 @@ Create a new collection
mutable_nft_name,
mutable_nft_properties,
mutable_nft_uri,
- royalty,
+ royalty
);
}
-
-
## Function `create_collection_object`
-public fun create_collection_object(creator: &signer, description: string::String, max_supply: u64, name: string::String, uri: string::String, mutable_description: bool, mutable_royalty: bool, mutable_uri: bool, mutable_nft_description: bool, mutable_nft_name: bool, mutable_nft_properties: bool, mutable_nft_uri: bool, royalty: decimal128::Decimal128): object::Object<soul_bound_token::SoulBoundTokenCollection>
+public fun create_collection_object(creator: &signer, description: string::String, max_supply: u64, name: string::String, uri: string::String, mutable_description: bool, mutable_royalty: bool, mutable_uri: bool, mutable_nft_description: bool, mutable_nft_name: bool, mutable_nft_properties: bool, mutable_nft_uri: bool, royalty: bigdecimal::BigDecimal): object::Object<soul_bound_token::SoulBoundTokenCollection>
-
-Implementation
+##### Implementation
public fun create_collection_object(
@@ -298,31 +282,38 @@ Create a new collection
mutable_nft_name: bool,
mutable_nft_properties: bool,
mutable_nft_uri: bool,
- royalty: Decimal128,
+ royalty: BigDecimal
): Object<SoulBoundTokenCollection> {
let creator_addr = signer::address_of(creator);
let royalty = royalty::create(royalty, creator_addr);
- let constructor_ref = collection::create_fixed_collection(
- creator,
- description,
- max_supply,
- name,
- option::some(royalty),
- uri,
- );
+ let constructor_ref =
+ collection::create_fixed_collection(
+ creator,
+ description,
+ max_supply,
+ name,
+ option::some(royalty),
+ uri
+ );
let object_signer = object::generate_signer(&constructor_ref);
- let mutator_ref = if (mutable_description || mutable_uri) {
- option::some(collection::generate_mutator_ref(&constructor_ref))
- } else {
- option::none()
- };
-
- let royalty_mutator_ref = if (mutable_royalty) {
- option::some(royalty::generate_mutator_ref(object::generate_extend_ref(&constructor_ref)))
- } else {
- option::none()
- };
+ let mutator_ref =
+ if (mutable_description || mutable_uri) {
+ option::some(collection::generate_mutator_ref(&constructor_ref))
+ } else {
+ option::none()
+ };
+
+ let royalty_mutator_ref =
+ if (mutable_royalty) {
+ option::some(
+ royalty::generate_mutator_ref(
+ object::generate_extend_ref(&constructor_ref)
+ )
+ )
+ } else {
+ option::none()
+ };
let soul_bound_token_collection = SoulBoundTokenCollection {
mutator_ref,
@@ -332,7 +323,7 @@ Create a new collection
mutable_nft_description,
mutable_nft_name,
mutable_nft_properties,
- mutable_nft_uri,
+ mutable_nft_uri
};
move_to(&object_signer, soul_bound_token_collection);
object::object_from_constructor_ref(&constructor_ref)
@@ -341,8 +332,6 @@ Create a new collection
-
-
## Function `mint`
@@ -355,8 +344,7 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-Implementation
+##### Implementation
public entry fun mint(
@@ -368,7 +356,7 @@ With an existing collection, directly mint a soul bound token into the recipient
property_keys: vector<String>,
property_types: vector<String>,
property_values: vector<vector<u8>>,
- soul_bound_to: address,
+ soul_bound_to: address
) acquires SoulBoundTokenCollection {
mint_soul_bound_token_object(
creator,
@@ -386,8 +374,6 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-
## Function `mint_soul_bound_token_object`
@@ -400,8 +386,7 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-Implementation
+##### Implementation
public fun mint_soul_bound_token_object(
@@ -413,18 +398,19 @@ With an existing collection, directly mint a soul bound token into the recipient
property_keys: vector<String>,
property_types: vector<String>,
property_values: vector<vector<u8>>,
- soul_bound_to: address,
+ soul_bound_to: address
): Object<SoulBoundToken> acquires SoulBoundTokenCollection {
- let constructor_ref = mint_internal(
- creator,
- collection,
- description,
- name,
- uri,
- property_keys,
- property_types,
- property_values,
- );
+ let constructor_ref =
+ mint_internal(
+ creator,
+ collection,
+ description,
+ name,
+ uri,
+ property_keys,
+ property_types,
+ property_values
+ );
let transfer_ref = object::generate_transfer_ref(&constructor_ref);
let linear_transfer_ref = object::generate_linear_transfer_ref(&transfer_ref);
@@ -437,104 +423,6 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-
-
-
-## Function `mint_internal`
-
-
-
-fun mint_internal(creator: &signer, collection: string::String, description: string::String, name: string::String, uri: string::String, property_keys: vector<string::String>, property_types: vector<string::String>, property_values: vector<vector<u8>>): object::ConstructorRef
-
-
-
-
-
-Implementation
-
-
-fun mint_internal(
- creator: &signer,
- collection: String,
- description: String,
- name: String,
- uri: String,
- property_keys: vector<String>,
- property_types: vector<String>,
- property_values: vector<vector<u8>>,
-): ConstructorRef acquires SoulBoundTokenCollection {
- let constructor_ref = nft::create(
- creator,
- collection,
- description,
- name,
- option::none(),
- uri,
- );
- let s = object::generate_signer(&constructor_ref);
-
- let object_signer = object::generate_signer(&constructor_ref);
-
- let collection_obj = collection_object(creator, &collection);
- let collection = borrow_collection(collection_obj);
-
- let mutator_ref = if (
- collection.mutable_nft_description
- || collection.mutable_nft_name
- || collection.mutable_nft_uri
- ) {
- option::some(nft::generate_mutator_ref(&constructor_ref))
- } else {
- option::none()
- };
-
- let soul_bound_token = SoulBoundToken {
- mutator_ref,
- property_mutator_ref: property_map::generate_mutator_ref(&s),
- };
- move_to(&object_signer, soul_bound_token);
-
- let properties = property_map::prepare_input(property_keys, property_types, property_values);
- property_map::init(&s, properties);
-
- constructor_ref
-}
-
-
-
-
-
-
-
-
-## Function `borrow`
-
-
-
-fun borrow<T: key>(nft: object::Object<T>): &soul_bound_token::SoulBoundToken
-
-
-
-
-
-Implementation
-
-
-inline fun borrow<T: key>(nft: Object<T>): &SoulBoundToken {
- let nft_address = object::object_address(nft);
- assert!(
- exists<SoulBoundToken>(nft_address),
- error::not_found(ENFT_DOES_NOT_EXIST),
- );
- borrow_global<SoulBoundToken>(nft_address)
-}
-
-
-
-
-
-
## Function `are_properties_mutable`
@@ -547,8 +435,7 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-Implementation
+##### Implementation
public fun are_properties_mutable<T: key>(nft: Object<T>): bool acquires SoulBoundTokenCollection {
@@ -559,8 +446,6 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-
## Function `is_mutable_description`
@@ -573,8 +458,7 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-Implementation
+##### Implementation
public fun is_mutable_description<T: key>(nft: Object<T>): bool acquires SoulBoundTokenCollection {
@@ -584,8 +468,6 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-
## Function `is_mutable_name`
@@ -598,8 +480,7 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-Implementation
+##### Implementation
public fun is_mutable_name<T: key>(nft: Object<T>): bool acquires SoulBoundTokenCollection {
@@ -609,8 +490,6 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-
## Function `is_mutable_uri`
@@ -623,8 +502,7 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-Implementation
+##### Implementation
public fun is_mutable_uri<T: key>(nft: Object<T>): bool acquires SoulBoundTokenCollection {
@@ -634,42 +512,6 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-
-
-
-## Function `authorized_borrow`
-
-
-
-fun authorized_borrow<T: key>(nft: object::Object<T>, creator: &signer): &soul_bound_token::SoulBoundToken
-
-
-
-
-
-Implementation
-
-
-inline fun authorized_borrow<T: key>(nft: Object<T>, creator: &signer): &SoulBoundToken {
- let nft_address = object::object_address(nft);
- assert!(
- exists<SoulBoundToken>(nft_address),
- error::not_found(ENFT_DOES_NOT_EXIST),
- );
-
- assert!(
- nft::creator(nft) == signer::address_of(creator),
- error::permission_denied(ENOT_CREATOR),
- );
- borrow_global<SoulBoundToken>(nft_address)
-}
-
-
-
-
-
-
## Function `set_description`
@@ -681,28 +523,26 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-Implementation
+##### Implementation
public entry fun set_description<T: key>(
- creator: &signer,
- nft: Object<T>,
- description: String,
+ creator: &signer, nft: Object<T>, description: String
) acquires SoulBoundTokenCollection, SoulBoundToken {
assert!(
is_mutable_description(nft),
- error::permission_denied(EFIELD_NOT_MUTABLE),
+ error::permission_denied(EFIELD_NOT_MUTABLE)
);
let soul_bound_token = authorized_borrow(nft, creator);
- nft::set_description(option::borrow(&soul_bound_token.mutator_ref), description);
+ nft::set_description(
+ option::borrow(&soul_bound_token.mutator_ref),
+ description
+ );
}
-
-
## Function `set_uri`
@@ -714,28 +554,26 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-Implementation
+##### Implementation
public entry fun set_uri<T: key>(
- creator: &signer,
- nft: Object<T>,
- uri: String,
+ creator: &signer, nft: Object<T>, uri: String
) acquires SoulBoundTokenCollection, SoulBoundToken {
assert!(
is_mutable_uri(nft),
- error::permission_denied(EFIELD_NOT_MUTABLE),
+ error::permission_denied(EFIELD_NOT_MUTABLE)
);
let soul_bound_token = authorized_borrow(nft, creator);
- nft::set_uri(option::borrow(&soul_bound_token.mutator_ref), uri);
+ nft::set_uri(
+ option::borrow(&soul_bound_token.mutator_ref),
+ uri
+ );
}
-
-
## Function `add_property`
@@ -747,8 +585,7 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-Implementation
+##### Implementation
public entry fun add_property<T: key>(
@@ -756,22 +593,25 @@ With an existing collection, directly mint a soul bound token into the recipient
nft: Object<T>,
key: String,
type: String,
- value: vector<u8>,
+ value: vector<u8>
) acquires SoulBoundTokenCollection, SoulBoundToken {
let soul_bound_token = authorized_borrow(nft, creator);
assert!(
are_properties_mutable(nft),
- error::permission_denied(EPROPERTIES_NOT_MUTABLE),
+ error::permission_denied(EPROPERTIES_NOT_MUTABLE)
);
- property_map::add(&soul_bound_token.property_mutator_ref, key, type, value);
+ property_map::add(
+ &soul_bound_token.property_mutator_ref,
+ key,
+ type,
+ value
+ );
}
-
-
## Function `add_typed_property`
@@ -783,30 +623,31 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-Implementation
+##### Implementation
public entry fun add_typed_property<T: key, V: drop>(
creator: &signer,
nft: Object<T>,
key: String,
- value: V,
+ value: V
) acquires SoulBoundTokenCollection, SoulBoundToken {
let soul_bound_token = authorized_borrow(nft, creator);
assert!(
are_properties_mutable(nft),
- error::permission_denied(EPROPERTIES_NOT_MUTABLE),
+ error::permission_denied(EPROPERTIES_NOT_MUTABLE)
);
- property_map::add_typed(&soul_bound_token.property_mutator_ref, key, value);
+ property_map::add_typed(
+ &soul_bound_token.property_mutator_ref,
+ key,
+ value
+ );
}
-
-
## Function `remove_property`
@@ -818,19 +659,16 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-Implementation
+##### Implementation
public entry fun remove_property<T: key>(
- creator: &signer,
- nft: Object<T>,
- key: String,
+ creator: &signer, nft: Object<T>, key: String
) acquires SoulBoundTokenCollection, SoulBoundToken {
let soul_bound_token = authorized_borrow(nft, creator);
assert!(
are_properties_mutable(nft),
- error::permission_denied(EPROPERTIES_NOT_MUTABLE),
+ error::permission_denied(EPROPERTIES_NOT_MUTABLE)
);
property_map::remove(&soul_bound_token.property_mutator_ref, &key);
@@ -839,8 +677,6 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-
## Function `update_property`
@@ -852,8 +688,7 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-Implementation
+##### Implementation
public entry fun update_property<T: key>(
@@ -861,22 +696,25 @@ With an existing collection, directly mint a soul bound token into the recipient
nft: Object<T>,
key: String,
type: String,
- value: vector<u8>,
+ value: vector<u8>
) acquires SoulBoundTokenCollection, SoulBoundToken {
let soul_bound_token = authorized_borrow(nft, creator);
assert!(
are_properties_mutable(nft),
- error::permission_denied(EPROPERTIES_NOT_MUTABLE),
+ error::permission_denied(EPROPERTIES_NOT_MUTABLE)
);
- property_map::update(&soul_bound_token.property_mutator_ref, &key, type, value);
+ property_map::update(
+ &soul_bound_token.property_mutator_ref,
+ &key,
+ type,
+ value
+ );
}
-
-
## Function `update_typed_property`
@@ -888,84 +726,31 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-Implementation
+##### Implementation
public entry fun update_typed_property<T: key, V: drop>(
creator: &signer,
nft: Object<T>,
key: String,
- value: V,
+ value: V
) acquires SoulBoundTokenCollection, SoulBoundToken {
let soul_bound_token = authorized_borrow(nft, creator);
assert!(
are_properties_mutable(nft),
- error::permission_denied(EPROPERTIES_NOT_MUTABLE),
+ error::permission_denied(EPROPERTIES_NOT_MUTABLE)
);
- property_map::update_typed(&soul_bound_token.property_mutator_ref, &key, value);
-}
-
-
-
-
-
-
-
-
-## Function `collection_object`
-
-
-
-fun collection_object(creator: &signer, name: &string::String): object::Object<soul_bound_token::SoulBoundTokenCollection>
-
-
-
-
-
-Implementation
-
-
-inline fun collection_object(creator: &signer, name: &String): Object<SoulBoundTokenCollection> {
- let collection_addr = collection::create_collection_address(signer::address_of(creator), name);
- object::address_to_object<SoulBoundTokenCollection>(collection_addr)
-}
-
-
-
-
-
-
-
-
-## Function `borrow_collection`
-
-
-
-fun borrow_collection<T: key>(nft: object::Object<T>): &soul_bound_token::SoulBoundTokenCollection
-
-
-
-
-
-Implementation
-
-
-inline fun borrow_collection<T: key>(nft: Object<T>): &SoulBoundTokenCollection {
- let collection_address = object::object_address(nft);
- assert!(
- exists<SoulBoundTokenCollection>(collection_address),
- error::not_found(ECOLLECTION_DOES_NOT_EXIST),
+ property_map::update_typed(
+ &soul_bound_token.property_mutator_ref,
+ &key,
+ value
);
- borrow_global<SoulBoundTokenCollection>(collection_address)
}
-
-
## Function `is_mutable_collection_description`
@@ -977,12 +762,11 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-Implementation
+##### Implementation
public fun is_mutable_collection_description<T: key>(
- collection: Object<T>,
+ collection: Object<T>
): bool acquires SoulBoundTokenCollection {
borrow_collection(collection).mutable_description
}
@@ -990,8 +774,6 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-
## Function `is_mutable_collection_royalty`
@@ -1003,12 +785,11 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-Implementation
+##### Implementation
public fun is_mutable_collection_royalty<T: key>(
- collection: Object<T>,
+ collection: Object<T>
): bool acquires SoulBoundTokenCollection {
option::is_some(&borrow_collection(collection).royalty_mutator_ref)
}
@@ -1016,8 +797,6 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-
## Function `is_mutable_collection_uri`
@@ -1029,12 +808,11 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-Implementation
+##### Implementation
public fun is_mutable_collection_uri<T: key>(
- collection: Object<T>,
+ collection: Object<T>
): bool acquires SoulBoundTokenCollection {
borrow_collection(collection).mutable_uri
}
@@ -1042,8 +820,6 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-
## Function `is_mutable_collection_nft_description`
@@ -1055,12 +831,11 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-Implementation
+##### Implementation
public fun is_mutable_collection_nft_description<T: key>(
- collection: Object<T>,
+ collection: Object<T>
): bool acquires SoulBoundTokenCollection {
borrow_collection(collection).mutable_nft_description
}
@@ -1068,8 +843,6 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-
## Function `is_mutable_collection_nft_name`
@@ -1081,12 +854,11 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-Implementation
+##### Implementation
public fun is_mutable_collection_nft_name<T: key>(
- collection: Object<T>,
+ collection: Object<T>
): bool acquires SoulBoundTokenCollection {
borrow_collection(collection).mutable_nft_name
}
@@ -1094,8 +866,6 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-
## Function `is_mutable_collection_nft_uri`
@@ -1107,12 +877,11 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-Implementation
+##### Implementation
public fun is_mutable_collection_nft_uri<T: key>(
- collection: Object<T>,
+ collection: Object<T>
): bool acquires SoulBoundTokenCollection {
borrow_collection(collection).mutable_nft_uri
}
@@ -1120,8 +889,6 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-
## Function `is_mutable_collection_nft_properties`
@@ -1133,12 +900,11 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-Implementation
+##### Implementation
public fun is_mutable_collection_nft_properties<T: key>(
- collection: Object<T>,
+ collection: Object<T>
): bool acquires SoulBoundTokenCollection {
borrow_collection(collection).mutable_nft_properties
}
@@ -1146,41 +912,6 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-
-
-
-## Function `authorized_borrow_collection`
-
-
-
-fun authorized_borrow_collection<T: key>(collection: object::Object<T>, creator: &signer): &soul_bound_token::SoulBoundTokenCollection
-
-
-
-
-
-Implementation
-
-
-inline fun authorized_borrow_collection<T: key>(collection: Object<T>, creator: &signer): &SoulBoundTokenCollection {
- let collection_address = object::object_address(collection);
- assert!(
- exists<SoulBoundTokenCollection>(collection_address),
- error::not_found(ECOLLECTION_DOES_NOT_EXIST),
- );
- assert!(
- collection::creator(collection) == signer::address_of(creator),
- error::permission_denied(ENOT_CREATOR),
- );
- borrow_global<SoulBoundTokenCollection>(collection_address)
-}
-
-
-
-
-
-
## Function `set_collection_description`
@@ -1192,28 +923,27 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-Implementation
+##### Implementation
public entry fun set_collection_description<T: key>(
- creator: &signer,
- collection: Object<T>,
- description: String,
+ creator: &signer, collection: Object<T>, description: String
) acquires SoulBoundTokenCollection {
- let soul_bound_token_collection = authorized_borrow_collection(collection, creator);
+ let soul_bound_token_collection =
+ authorized_borrow_collection(collection, creator);
assert!(
soul_bound_token_collection.mutable_description,
- error::permission_denied(EFIELD_NOT_MUTABLE),
+ error::permission_denied(EFIELD_NOT_MUTABLE)
+ );
+ collection::set_description(
+ option::borrow(&soul_bound_token_collection.mutator_ref),
+ description
);
- collection::set_description(option::borrow(&soul_bound_token_collection.mutator_ref), description);
}
-
-
## Function `set_collection_royalties`
@@ -1225,48 +955,46 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-Implementation
+##### Implementation
public fun set_collection_royalties<T: key>(
- creator: &signer,
- collection: Object<T>,
- royalty: royalty::Royalty,
+ creator: &signer, collection: Object<T>, royalty: royalty::Royalty
) acquires SoulBoundTokenCollection {
- let soul_bound_token_collection = authorized_borrow_collection(collection, creator);
+ let soul_bound_token_collection =
+ authorized_borrow_collection(collection, creator);
assert!(
option::is_some(&soul_bound_token_collection.royalty_mutator_ref),
- error::permission_denied(EFIELD_NOT_MUTABLE),
+ error::permission_denied(EFIELD_NOT_MUTABLE)
+ );
+ royalty::update(
+ option::borrow(&soul_bound_token_collection.royalty_mutator_ref),
+ royalty
);
- royalty::update(option::borrow(&soul_bound_token_collection.royalty_mutator_ref), royalty);
}
-
-
## Function `set_collection_royalties_call`
-entry fun set_collection_royalties_call<T: key>(creator: &signer, collection: object::Object<T>, royalty: decimal128::Decimal128, payee_address: address)
+entry fun set_collection_royalties_call<T: key>(creator: &signer, collection: object::Object<T>, royalty: bigdecimal::BigDecimal, payee_address: address)
-
-Implementation
+##### Implementation
entry fun set_collection_royalties_call<T: key>(
creator: &signer,
collection: Object<T>,
- royalty: Decimal128,
- payee_address: address,
+ royalty: BigDecimal,
+ payee_address: address
) acquires SoulBoundTokenCollection {
let royalty = royalty::create(royalty, payee_address);
set_collection_royalties(creator, collection, royalty);
@@ -1275,8 +1003,6 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-
## Function `set_collection_uri`
@@ -1288,24 +1014,21 @@ With an existing collection, directly mint a soul bound token into the recipient
-
-Implementation
+##### Implementation
public entry fun set_collection_uri<T: key>(
- creator: &signer,
- collection: Object<T>,
- uri: String,
+ creator: &signer, collection: Object<T>, uri: String
) acquires SoulBoundTokenCollection {
- let soul_bound_token_collection = authorized_borrow_collection(collection, creator);
+ let soul_bound_token_collection =
+ authorized_borrow_collection(collection, creator);
assert!(
soul_bound_token_collection.mutable_uri,
- error::permission_denied(EFIELD_NOT_MUTABLE),
+ error::permission_denied(EFIELD_NOT_MUTABLE)
+ );
+ collection::set_uri(
+ option::borrow(&soul_bound_token_collection.mutator_ref),
+ uri
);
- collection::set_uri(option::borrow(&soul_bound_token_collection.mutator_ref), uri);
}
-
-
-
-
diff --git a/initia_stdlib/doc/stableswap.md b/initia_stdlib/doc/stableswap.md
index 4c5e537..e26a065 100644
--- a/initia_stdlib/doc/stableswap.md
+++ b/initia_stdlib/doc/stableswap.md
@@ -7,48 +7,48 @@
- [Resource `ModuleStore`](#0x1_stableswap_ModuleStore)
- [Resource `Pool`](#0x1_stableswap_Pool)
-- [Struct `CreatePairEvent`](#0x1_stableswap_CreatePairEvent)
+- [Struct `CreatePoolEvent`](#0x1_stableswap_CreatePoolEvent)
- [Struct `ProvideEvent`](#0x1_stableswap_ProvideEvent)
- [Struct `WithdrawEvent`](#0x1_stableswap_WithdrawEvent)
- [Struct `SwapEvent`](#0x1_stableswap_SwapEvent)
+- [Struct `UpdateSwapFeeEvent`](#0x1_stableswap_UpdateSwapFeeEvent)
+- [Struct `UpdateAnnEvent`](#0x1_stableswap_UpdateAnnEvent)
- [Struct `Ann`](#0x1_stableswap_Ann)
-- [Struct `PairResponse`](#0x1_stableswap_PairResponse)
+- [Struct `PoolResponse`](#0x1_stableswap_PoolResponse)
- [Constants](#@Constants_0)
- [Function `get_swap_simulation`](#0x1_stableswap_get_swap_simulation)
+- [Function `get_swap_simulation_given_out`](#0x1_stableswap_get_swap_simulation_given_out)
- [Function `get_swap_simulation_by_denom`](#0x1_stableswap_get_swap_simulation_by_denom)
-- [Function `get_pair`](#0x1_stableswap_get_pair)
-- [Function `get_all_pairs`](#0x1_stableswap_get_all_pairs)
-- [Function `init_module`](#0x1_stableswap_init_module)
-- [Function `unpack_pair_response`](#0x1_stableswap_unpack_pair_response)
-- [Function `create_pair_script`](#0x1_stableswap_create_pair_script)
+- [Function `get_provide_simulation`](#0x1_stableswap_get_provide_simulation)
+- [Function `get_imbalance_withdraw_simulation`](#0x1_stableswap_get_imbalance_withdraw_simulation)
+- [Function `get_single_asset_withdraw_simulation`](#0x1_stableswap_get_single_asset_withdraw_simulation)
+- [Function `get_pool`](#0x1_stableswap_get_pool)
+- [Function `get_all_pools`](#0x1_stableswap_get_all_pools)
+- [Function `spot_price`](#0x1_stableswap_spot_price)
+- [Function `unpack_pool_response`](#0x1_stableswap_unpack_pool_response)
+- [Function `create_pool_script`](#0x1_stableswap_create_pool_script)
- [Function `update_swap_fee_rate`](#0x1_stableswap_update_swap_fee_rate)
- [Function `update_ann`](#0x1_stableswap_update_ann)
- [Function `provide_liquidity_script`](#0x1_stableswap_provide_liquidity_script)
- [Function `withdraw_liquidity_script`](#0x1_stableswap_withdraw_liquidity_script)
+- [Function `imbalance_withdraw_liquidity_script`](#0x1_stableswap_imbalance_withdraw_liquidity_script)
+- [Function `single_asset_withdraw_liquidity_script`](#0x1_stableswap_single_asset_withdraw_liquidity_script)
- [Function `swap_script`](#0x1_stableswap_swap_script)
-- [Function `create_pair`](#0x1_stableswap_create_pair)
+- [Function `create_pool`](#0x1_stableswap_create_pool)
- [Function `provide_liquidity`](#0x1_stableswap_provide_liquidity)
- [Function `withdraw_liquidity`](#0x1_stableswap_withdraw_liquidity)
+- [Function `single_asset_withdraw_liquidity`](#0x1_stableswap_single_asset_withdraw_liquidity)
- [Function `swap`](#0x1_stableswap_swap)
- [Function `pool_info`](#0x1_stableswap_pool_info)
-- [Function `borrow_pool`](#0x1_stableswap_borrow_pool)
-- [Function `borrow_pool_mut`](#0x1_stableswap_borrow_pool_mut)
-- [Function `get_current_ann`](#0x1_stableswap_get_current_ann)
-- [Function `check_coin_metadata`](#0x1_stableswap_check_coin_metadata)
-- [Function `get_pool_amounts`](#0x1_stableswap_get_pool_amounts)
-- [Function `get_amounts`](#0x1_stableswap_get_amounts)
-- [Function `get_coin_addresses`](#0x1_stableswap_get_coin_addresses)
-- [Function `get_d`](#0x1_stableswap_get_d)
-- [Function `get_y`](#0x1_stableswap_get_y)
+- [Function `single_asset_withdraw_simulation`](#0x1_stableswap_single_asset_withdraw_simulation)
+- [Function `imbalance_withdraw_simulation`](#0x1_stableswap_imbalance_withdraw_simulation)
- [Function `swap_simulation`](#0x1_stableswap_swap_simulation)
-- [Function `mul_div_u64`](#0x1_stableswap_mul_div_u64)
-- [Function `mul_div_u128`](#0x1_stableswap_mul_div_u128)
-- [Function `check_chain_permission`](#0x1_stableswap_check_chain_permission)
+- [Function `provide_simulation`](#0x1_stableswap_provide_simulation)
-use 0x1::block;
+use 0x1::bigdecimal;
+use 0x1::block;
use 0x1::coin;
-use 0x1::decimal128;
use 0x1::error;
use 0x1::event;
use 0x1::fungible_asset;
@@ -74,19 +74,18 @@
-
-Fields
+##### Fields
-
-
pairs: table::Table<address, bool>
+pools: table::Table<address, bool>
-
-
-
pair_count: u64
+pool_count: u64
-
@@ -94,8 +93,6 @@
-
-
## Resource `Pool`
@@ -107,8 +104,7 @@
-
-Fields
+##### Fields
@@ -125,7 +121,7 @@
ANN
-
-
swap_fee_rate: decimal128::Decimal128
+swap_fee_rate: bigdecimal::BigDecimal
-
swap fee
@@ -157,22 +153,19 @@
-
-
-
+
-## Struct `CreatePairEvent`
+## Struct `CreatePoolEvent`
#[event]
-struct CreatePairEvent has drop, store
+struct CreatePoolEvent has drop, store
-
-Fields
+##### Fields
@@ -195,7 +188,7 @@
-
-
swap_fee_rate: decimal128::Decimal128
+swap_fee_rate: bigdecimal::BigDecimal
-
@@ -203,8 +196,6 @@
-
-
## Struct `ProvideEvent`
@@ -217,8 +208,7 @@
-
-Fields
+##### Fields
@@ -233,6 +223,12 @@
-
+
+-
+
fee_amounts: vector<u64>
+
+-
+
-
liquidity_token: address
@@ -249,8 +245,6 @@
-
-
## Struct `WithdrawEvent`
@@ -263,8 +257,7 @@
-
-Fields
+##### Fields
@@ -279,6 +272,12 @@
-
+
+-
+
fee_amounts: vector<u64>
+
+-
+
-
liquidity_token: address
@@ -295,8 +294,6 @@
-
-
## Struct `SwapEvent`
@@ -309,8 +306,7 @@
-
-Fields
+##### Fields
@@ -353,7 +349,67 @@
-
+
+
+## Struct `UpdateSwapFeeEvent`
+
+
+
+#[event]
+struct UpdateSwapFeeEvent has drop, store
+
+
+
+
+##### Fields
+
+
+
+-
+
liquidity_token: address
+
+-
+
+
+-
+
swap_fee_rate: bigdecimal::BigDecimal
+
+-
+
+
+
+
+
+
+
+## Struct `UpdateAnnEvent`
+
+
+
+#[event]
+struct UpdateAnnEvent has drop, store
+
+
+
+
+##### Fields
+
+
+
+-
+
liquidity_token: address
+
+-
+
+
+-
+
ann: stableswap::Ann
+
+-
+
+
+
+
@@ -366,8 +422,7 @@
-
-Fields
+##### Fields
@@ -398,21 +453,18 @@
-
-
-
+
-## Struct `PairResponse`
+## Struct `PoolResponse`
-struct PairResponse has copy, drop, store
+struct PoolResponse has copy, drop, store
-
-Fields
+##### Fields
@@ -441,7 +493,7 @@
-
-
swap_fee_rate: decimal128::Decimal128
+swap_fee_rate: bigdecimal::BigDecimal
-
@@ -449,13 +501,21 @@
-
-
## Constants
+
+
+Only chain can execute.
+
+
+const EUNAUTHORIZED: u64 = 7;
+
+
+
+
Wrong coin type given
@@ -575,16 +635,6 @@ All start_after must be provided or not
-
-
-Only chain can execute.
-
-
-const EUNAUTHORIZED: u64 = 7;
-
-
-
-
end time must be larger than start time
@@ -605,29 +655,29 @@ Can not withdraw zero liquidity
-
+
-const MAX_FEE_RATE: u128 = 10000000000000000;
+const MAX_LIMIT: u8 = 30;
-
+
-const MAX_LIMIT: u8 = 30;
+const A_PRECISION: u256 = 100;
-
+
-const A_PRECISION: u256 = 100;
+const EMAX_LIQUIDITY: u64 = 21;
@@ -649,27 +699,28 @@ Return swap simulation result
#[view]
-public fun get_swap_simulation(pair: object::Object<stableswap::Pool>, offer_metadata: object::Object<fungible_asset::Metadata>, return_metadata: object::Object<fungible_asset::Metadata>, offer_amount: u64): u64
+public fun get_swap_simulation(pool_obj: object::Object<stableswap::Pool>, offer_metadata: object::Object<fungible_asset::Metadata>, return_metadata: object::Object<fungible_asset::Metadata>, offer_amount: u64): u64
-
-Implementation
+##### Implementation
public fun get_swap_simulation(
- pair: Object<Pool>,
+ pool_obj: Object<Pool>,
offer_metadata: Object<Metadata>,
return_metadata: Object<Metadata>,
- offer_amount: u64,
+ offer_amount: u64
): u64 acquires Pool {
- let (return_amount, fee_amount) = swap_simulation(
- pair,
- offer_metadata,
- return_metadata,
- offer_amount,
- );
+ let (return_amount, fee_amount) =
+ swap_simulation(
+ pool_obj,
+ offer_metadata,
+ return_metadata,
+ offer_amount,
+ true
+ );
return_amount - fee_amount
}
@@ -677,7 +728,42 @@ Return swap simulation result
-
+
+
+## Function `get_swap_simulation_given_out`
+
+Return swap simulation result
+
+
+#[view]
+public fun get_swap_simulation_given_out(pool_obj: object::Object<stableswap::Pool>, offer_metadata: object::Object<fungible_asset::Metadata>, return_metadata: object::Object<fungible_asset::Metadata>, return_amount: u64): u64
+
+
+
+
+##### Implementation
+
+
+public fun get_swap_simulation_given_out(
+ pool_obj: Object<Pool>,
+ offer_metadata: Object<Metadata>,
+ return_metadata: Object<Metadata>,
+ return_amount: u64
+): u64 acquires Pool {
+ let (offer_amount, _) =
+ swap_simulation(
+ pool_obj,
+ offer_metadata,
+ return_metadata,
+ return_amount,
+ false
+ );
+
+ offer_amount
+}
+
+
+
@@ -686,54 +772,151 @@ Return swap simulation result
#[view]
-public fun get_swap_simulation_by_denom(pair: object::Object<stableswap::Pool>, offer_denom: string::String, return_denom: string::String, offer_amount: u64): u64
+public fun get_swap_simulation_by_denom(pool_obj: object::Object<stableswap::Pool>, offer_denom: string::String, return_denom: string::String, offer_amount: u64): u64
-
-Implementation
+##### Implementation
public fun get_swap_simulation_by_denom(
- pair: Object<Pool>,
+ pool_obj: Object<Pool>,
offer_denom: String,
return_denom: String,
- offer_amount: u64,
+ offer_amount: u64
): u64 acquires Pool {
let offer_metadata = coin::denom_to_metadata(offer_denom);
let return_metadata = coin::denom_to_metadata(return_denom);
- get_swap_simulation(pair, offer_metadata, return_metadata, offer_amount)
+ get_swap_simulation(
+ pool_obj,
+ offer_metadata,
+ return_metadata,
+ offer_amount
+ )
+}
+
+
+
+
+
+
+## Function `get_provide_simulation`
+
+
+
+#[view]
+public fun get_provide_simulation(pool_obj: object::Object<stableswap::Pool>, coin_amounts: vector<u64>): u64
+
+
+
+
+##### Implementation
+
+
+public fun get_provide_simulation(
+ pool_obj: Object<Pool>, coin_amounts: vector<u64>
+): u64 acquires Pool {
+ let (liquidity_amount, _) = provide_simulation(pool_obj, coin_amounts);
+ liquidity_amount
+}
+
+
+
+
+
+
+## Function `get_imbalance_withdraw_simulation`
+
+
+
+#[view]
+public fun get_imbalance_withdraw_simulation(pool_obj: object::Object<stableswap::Pool>, coin_amounts: vector<u64>): u64
+
+
+
+
+##### Implementation
+
+
+public fun get_imbalance_withdraw_simulation(
+ pool_obj: Object<Pool>, coin_amounts: vector<u64>
+): u64 acquires Pool {
+ let (liquidity_amount, _) =
+ imbalance_withdraw_simulation(
+ pool_obj,
+ coin_amounts,
+ option::none()
+ );
+ liquidity_amount
}
-
+
+
+## Function `get_single_asset_withdraw_simulation`
+
+
+
+#[view]
+public fun get_single_asset_withdraw_simulation(pool_obj: object::Object<stableswap::Pool>, return_coin_metadata: object::Object<fungible_asset::Metadata>, liquidity_amount: u64): u64
+
+
+
+
+##### Implementation
+
+
+public fun get_single_asset_withdraw_simulation(
+ pool_obj: Object<Pool>,
+ return_coin_metadata: Object<Metadata>,
+ liquidity_amount: u64
+): u64 acquires Pool {
+ let pool = borrow_pool(pool_obj);
+
+ // get return index
+ let (found, return_index) = vector::index_of(
+ &pool.coin_metadata, &return_coin_metadata
+ );
+ assert!(found, error::invalid_argument(ECOIN_TYPE));
+
+ let (liquidity_amount, _) =
+ single_asset_withdraw_simulation(
+ pool_obj,
+ liquidity_amount,
+ return_index
+ );
+ liquidity_amount
+}
+
-
-## Function `get_pair`
+
+
+
+## Function `get_pool`
#[view]
-public fun get_pair(pool: object::Object<stableswap::Pool>): stableswap::PairResponse
+public fun get_pool(pool: object::Object<stableswap::Pool>): stableswap::PoolResponse
-
-Implementation
+##### Implementation
-public fun get_pair(
- pool: Object<Pool>,
-): PairResponse acquires Pool {
+public fun get_pool(pool: Object<Pool>): PoolResponse acquires Pool {
let (coin_metadata, coin_balances, current_ann, swap_fee_rate) = pool_info(pool);
- let coin_denoms = vector::map(coin_metadata, |metadata| coin::metadata_to_denom(metadata));
+ let coin_denoms = vector::map(
+ coin_metadata,
+ |metadata| coin::metadata_to_denom(metadata)
+ );
- PairResponse {
+ PoolResponse {
coin_metadata,
coin_denoms,
coin_balances,
@@ -745,28 +928,24 @@ Return swap simulation result
-
+
-
-
-## Function `get_all_pairs`
+## Function `get_all_pools`
#[view]
-public fun get_all_pairs(start_after: option::Option<address>, limit: u8): vector<stableswap::PairResponse>
+public fun get_all_pools(start_after: option::Option<address>, limit: u8): vector<stableswap::PoolResponse>
-
-Implementation
+##### Implementation
-public fun get_all_pairs(
- start_after: Option<address>,
- limit: u8,
-): vector<PairResponse> acquires ModuleStore, Pool {
+public fun get_all_pools(
+ start_after: Option<address>, limit: u8
+): vector<PoolResponse> acquires ModuleStore, Pool {
if (limit > MAX_LIMIT) {
limit = MAX_LIMIT;
};
@@ -774,17 +953,18 @@ Return swap simulation result
let module_store = borrow_global<ModuleStore>(@initia_std);
let res = vector[];
- let pairs_iter = table::iter(
- &module_store.pairs,
+ let pools_iter = table::iter(
+ &module_store.pools,
option::none(),
start_after,
- 2,
+ 2
);
- while (vector::length(&res) < (limit as u64) && table::prepare<address, bool>(&mut pairs_iter)) {
- let (key, _) = table::next<address, bool>(&mut pairs_iter);
- let pair_response = get_pair(object::address_to_object<Pool>(key));
- vector::push_back(&mut res, pair_response)
+ while (vector::length(&res) < (limit as u64)
+ && table::prepare<address, bool>(pools_iter)) {
+ let (key, _) = table::next<address, bool>(pools_iter);
+ let pool_response = get_pool(object::address_to_object<Pool>(key));
+ vector::push_back(&mut res, pool_response)
};
res
@@ -793,85 +973,124 @@ Return swap simulation result
-
-
-
+
-## Function `init_module`
+## Function `spot_price`
-fun init_module(chain: &signer)
+#[view]
+public fun spot_price(pool_obj: object::Object<stableswap::Pool>, base_metadata: object::Object<fungible_asset::Metadata>, quote_metadata: object::Object<fungible_asset::Metadata>): bigdecimal::BigDecimal
-
-Implementation
+##### Implementation
+
+public fun spot_price(
+ pool_obj: Object<Pool>,
+ base_metadata: Object<Metadata>,
+ quote_metadata: Object<Metadata>
+): BigDecimal acquires Pool {
+ let pool = borrow_pool(pool_obj);
+ let ann = get_current_ann(&pool.ann);
+ let pool_addr = object::object_address(&pool_obj);
+ let amounts = get_pool_amounts(pool_addr, pool.coin_metadata);
+ let d = get_d(amounts, ann);
+ let swap_amount = d / 1000;
+
+ if (swap_amount < 1000000) {
+ let len = vector::length(&amounts);
+ let i = 0;
+ while (i < len) {
+ let amount = vector::borrow_mut(&mut amounts, i);
+ *amount = *amount * 1000000;
+ i = i + 1;
+ };
+
+ swap_amount = swap_amount * 1000000;
+ };
+
+ let (base_return_amount, _) =
+ swap_simulation_with_given_amounts(
+ pool_obj,
+ amounts,
+ quote_metadata,
+ base_metadata,
+ swap_amount,
+ true
+ );
+ let (quote_return_amount, _) =
+ swap_simulation_with_given_amounts(
+ pool_obj,
+ amounts,
+ base_metadata,
+ quote_metadata,
+ swap_amount,
+ true
+ );
-fun init_module(chain: &signer) {
- move_to(chain, ModuleStore { pairs: table::new(), pair_count: 0 })
+ bigdecimal::from_ratio_u64(
+ quote_return_amount + swap_amount,
+ base_return_amount + swap_amount
+ )
}
-
-
-
+
-## Function `unpack_pair_response`
+## Function `unpack_pool_response`
-public fun unpack_pair_response(pair_response: &stableswap::PairResponse): (vector<object::Object<fungible_asset::Metadata>>, vector<string::String>, vector<u64>, u64, decimal128::Decimal128)
+public fun unpack_pool_response(pool_response: &stableswap::PoolResponse): (vector<object::Object<fungible_asset::Metadata>>, vector<string::String>, vector<u64>, u64, bigdecimal::BigDecimal)
-
-Implementation
+##### Implementation
-public fun unpack_pair_response(pair_response: &PairResponse): (vector<Object<Metadata>>, vector<String>, vector<u64>, u64, Decimal128) {
+public fun unpack_pool_response(
+ pool_response: &PoolResponse
+): (vector<Object<Metadata>>, vector<String>, vector<u64>, u64, BigDecimal) {
(
- pair_response.coin_metadata,
- pair_response.coin_denoms,
- pair_response.coin_balances,
- pair_response.current_ann,
- pair_response.swap_fee_rate,
+ pool_response.coin_metadata,
+ pool_response.coin_denoms,
+ pool_response.coin_balances,
+ pool_response.current_ann,
+ pool_response.swap_fee_rate
)
}
-
+
-
+## Function `create_pool_script`
-## Function `create_pair_script`
-
-public entry fun create_pair_script(creator: &signer, name: string::String, symbol: string::String, swap_fee_rate: decimal128::Decimal128, coin_metadata: vector<object::Object<fungible_asset::Metadata>>, coin_amounts: vector<u64>, ann: u64)
+public entry fun create_pool_script(creator: &signer, name: string::String, symbol: string::String, swap_fee_rate: bigdecimal::BigDecimal, coin_metadata: vector<object::Object<fungible_asset::Metadata>>, coin_amounts: vector<u64>, ann: u64)
-
-Implementation
+##### Implementation
-public entry fun create_pair_script(
+public entry fun create_pool_script(
creator: &signer,
name: String,
symbol: String,
- swap_fee_rate: Decimal128,
+ swap_fee_rate: BigDecimal,
coin_metadata: vector<Object<Metadata>>,
coin_amounts: vector<u64>,
- ann: u64,
+ ann: u64
) acquires Pool, ModuleStore {
let coins: vector<FungibleAsset> = vector[];
let i = 0;
@@ -879,134 +1098,162 @@ Return swap simulation result
while (i < n) {
let metadata = *vector::borrow(&coin_metadata, i);
let amount = *vector::borrow(&coin_amounts, i);
- vector::push_back(&mut coins, primary_fungible_store::withdraw(creator, metadata, amount));
+ vector::push_back(
+ &mut coins,
+ primary_fungible_store::withdraw(creator, metadata, amount)
+ );
i = i + 1;
};
- let liquidity_token = create_pair(creator, name, symbol, swap_fee_rate, coins, ann);
+ let liquidity_token = create_pool(
+ creator,
+ name,
+ symbol,
+ swap_fee_rate,
+ coins,
+ ann
+ );
primary_fungible_store::deposit(signer::address_of(creator), liquidity_token);
}
-
-
## Function `update_swap_fee_rate`
-public entry fun update_swap_fee_rate(account: &signer, pair: object::Object<stableswap::Pool>, new_swap_fee_rate: decimal128::Decimal128)
+public entry fun update_swap_fee_rate(account: &signer, pool_obj: object::Object<stableswap::Pool>, new_swap_fee_rate: bigdecimal::BigDecimal)
-
-Implementation
+##### Implementation
-public entry fun update_swap_fee_rate(account: &signer, pair: Object<Pool>, new_swap_fee_rate: Decimal128) acquires Pool {
+public entry fun update_swap_fee_rate(
+ account: &signer, pool_obj: Object<Pool>, new_swap_fee_rate: BigDecimal
+) acquires Pool {
check_chain_permission(account);
- let pool = borrow_pool_mut(pair);
+ let pool = borrow_pool_mut(pool_obj);
pool.swap_fee_rate = new_swap_fee_rate;
+
+ event::emit(
+ UpdateSwapFeeEvent {
+ liquidity_token: object::object_address(&pool_obj),
+ swap_fee_rate: new_swap_fee_rate
+ }
+ )
}
-
-
## Function `update_ann`
-public entry fun update_ann(account: &signer, pair: object::Object<stableswap::Pool>, ann_after: u64, timestamp_after: u64)
+public entry fun update_ann(account: &signer, pool_obj: object::Object<stableswap::Pool>, ann_after: u64, timestamp_after: u64)
-
-Implementation
+##### Implementation
-public entry fun update_ann(account: &signer, pair: Object<Pool>, ann_after: u64, timestamp_after: u64) acquires Pool {
+public entry fun update_ann(
+ account: &signer,
+ pool_obj: Object<Pool>,
+ ann_after: u64,
+ timestamp_after: u64
+) acquires Pool {
check_chain_permission(account);
- let (_, timestamp) = block::get_block_info();
- let pool = borrow_pool_mut(pair);
+ let (_, timestamp) = block::get_block_info();
+ let pool = borrow_pool_mut(pool_obj);
pool.ann.ann_before = get_current_ann(&pool.ann);
- pool.ann.timestamp_before = timestamp;
+ pool.ann.timestamp_before = timestamp;
pool.ann.ann_after = ann_after;
pool.ann.timestamp_after = timestamp_after;
+
+ event::emit(
+ UpdateAnnEvent {
+ liquidity_token: object::object_address(&pool_obj),
+ ann: pool.ann
+ }
+ )
}
-
-
## Function `provide_liquidity_script`
-public entry fun provide_liquidity_script(account: &signer, pair: object::Object<stableswap::Pool>, coin_amounts: vector<u64>, min_liquidity: option::Option<u64>)
+public entry fun provide_liquidity_script(account: &signer, pool_obj: object::Object<stableswap::Pool>, coin_amounts: vector<u64>, min_liquidity: option::Option<u64>)
-
-Implementation
+##### Implementation
public entry fun provide_liquidity_script(
account: &signer,
- pair: Object<Pool>,
+ pool_obj: Object<Pool>,
coin_amounts: vector<u64>,
- min_liquidity: Option<u64>,
+ min_liquidity: Option<u64>
) acquires Pool {
let coins: vector<FungibleAsset> = vector[];
- let pool = borrow_pool(pair);
+ let pool = borrow_pool(pool_obj);
let i = 0;
let n = vector::length(&coin_amounts);
while (i < n) {
let metadata = *vector::borrow(&pool.coin_metadata, i);
let amount = *vector::borrow(&coin_amounts, i);
- vector::push_back(&mut coins, primary_fungible_store::withdraw(account, metadata, amount));
+ vector::push_back(
+ &mut coins,
+ primary_fungible_store::withdraw(account, metadata, amount)
+ );
i = i + 1;
};
- let liquidity_token = provide_liquidity(pair, coins, min_liquidity);
+ let liquidity_token = provide_liquidity(pool_obj, coins, min_liquidity);
primary_fungible_store::deposit(signer::address_of(account), liquidity_token);
}
-
-
## Function `withdraw_liquidity_script`
-public entry fun withdraw_liquidity_script(account: &signer, pair: object::Object<stableswap::Pool>, liquidity_amount: u64, min_return_amounts: vector<option::Option<u64>>)
+public entry fun withdraw_liquidity_script(account: &signer, pool_obj: object::Object<stableswap::Pool>, liquidity_amount: u64, min_return_amounts: vector<option::Option<u64>>)
-
-Implementation
+##### Implementation
-public entry fun withdraw_liquidity_script(account: &signer, pair: Object<Pool>, liquidity_amount: u64, min_return_amounts: vector<Option<u64>>) acquires Pool {
- let liquidity_token = primary_fungible_store::withdraw(account, pair, liquidity_amount);
+public entry fun withdraw_liquidity_script(
+ account: &signer,
+ pool_obj: Object<Pool>,
+ liquidity_amount: u64,
+ min_return_amounts: vector<Option<u64>>
+) acquires Pool {
+ let liquidity_token =
+ primary_fungible_store::withdraw(account, pool_obj, liquidity_amount);
let coins = withdraw_liquidity(liquidity_token, min_return_amounts);
let i = 0;
@@ -1023,84 +1270,192 @@ Return swap simulation result
-
-
-
+
-## Function `swap_script`
+## Function `imbalance_withdraw_liquidity_script`
-public entry fun swap_script(account: &signer, pair: object::Object<stableswap::Pool>, offer_coin_metadata: object::Object<fungible_asset::Metadata>, return_coin_metadata: object::Object<fungible_asset::Metadata>, offer_amount: u64, min_return_amount: option::Option<u64>)
+public entry fun imbalance_withdraw_liquidity_script(account: &signer, pool_obj: object::Object<stableswap::Pool>, coin_amounts: vector<u64>, max_liquidity: option::Option<u64>)
-
-Implementation
+##### Implementation
-public entry fun swap_script(
+public entry fun imbalance_withdraw_liquidity_script(
account: &signer,
- pair: Object<Pool>,
- offer_coin_metadata: Object<Metadata>,
- return_coin_metadata: Object<Metadata>,
- offer_amount: u64,
- min_return_amount: Option<u64>,
-) acquires Pool{
- let offer_coin = primary_fungible_store::withdraw(account, offer_coin_metadata, offer_amount);
- let return_coin = swap(pair, offer_coin, return_coin_metadata, min_return_amount);
- primary_fungible_store::deposit(signer::address_of(account), return_coin);
+ pool_obj: Object<Pool>,
+ coin_amounts: vector<u64>,
+ max_liquidity: Option<u64>
+) acquires Pool {
+ let (liquidity_amount, fee_amounts) =
+ imbalance_withdraw_simulation(
+ pool_obj,
+ coin_amounts,
+ max_liquidity
+ );
+ let liquidity_token =
+ primary_fungible_store::withdraw(account, pool_obj, liquidity_amount);
+ let pool = borrow_pool(pool_obj);
+ let pool_signer = object::generate_signer_for_extending(&pool.extend_ref);
+ coin::burn(&pool.burn_cap, liquidity_token);
+
+ let n = vector::length(&pool.coin_metadata);
+
+ let i = 0;
+ while (i < n) {
+ let coin_metadata = *vector::borrow(&pool.coin_metadata, i);
+ let amount = *vector::borrow(&mut coin_amounts, i);
+ let coin =
+ primary_fungible_store::withdraw(&pool_signer, coin_metadata, amount);
+ primary_fungible_store::deposit(signer::address_of(account), coin);
+ i = i + 1;
+ };
+
+ event::emit<WithdrawEvent>(
+ WithdrawEvent {
+ coins: get_coin_addresses(pool.coin_metadata),
+ coin_amounts,
+ fee_amounts,
+ liquidity_token: object::object_address(&pool_obj),
+ liquidity: liquidity_amount
+ }
+ );
}
-
+
-
+## Function `single_asset_withdraw_liquidity_script`
-## Function `create_pair`
-
-public fun create_pair(creator: &signer, name: string::String, symbol: string::String, swap_fee_rate: decimal128::Decimal128, coins: vector<fungible_asset::FungibleAsset>, ann: u64): fungible_asset::FungibleAsset
+public entry fun single_asset_withdraw_liquidity_script(account: &signer, pool_obj: object::Object<stableswap::Pool>, return_coin_metadata: object::Object<fungible_asset::Metadata>, liquidity_amount: u64, min_return_amount: option::Option<u64>)
-
-Implementation
+##### Implementation
-public fun create_pair(
- creator: &signer,
- name: String,
- symbol: String,
- swap_fee_rate: Decimal128,
+public entry fun single_asset_withdraw_liquidity_script(
+ account: &signer,
+ pool_obj: Object<Pool>,
+ return_coin_metadata: Object<Metadata>,
+ liquidity_amount: u64,
+ min_return_amount: Option<u64>
+) acquires Pool {
+ let liquidity_token =
+ primary_fungible_store::withdraw(account, pool_obj, liquidity_amount);
+ let return_coin =
+ single_asset_withdraw_liquidity(
+ liquidity_token,
+ return_coin_metadata,
+ min_return_amount
+ );
+ primary_fungible_store::deposit(signer::address_of(account), return_coin);
+}
+
+
+
+
+
+
+## Function `swap_script`
+
+
+
+public entry fun swap_script(account: &signer, pool_obj: object::Object<stableswap::Pool>, offer_coin_metadata: object::Object<fungible_asset::Metadata>, return_coin_metadata: object::Object<fungible_asset::Metadata>, offer_amount: u64, min_return_amount: option::Option<u64>)
+
+
+
+
+##### Implementation
+
+
+public entry fun swap_script(
+ account: &signer,
+ pool_obj: Object<Pool>,
+ offer_coin_metadata: Object<Metadata>,
+ return_coin_metadata: Object<Metadata>,
+ offer_amount: u64,
+ min_return_amount: Option<u64>
+) acquires Pool {
+ let offer_coin =
+ primary_fungible_store::withdraw(
+ account,
+ offer_coin_metadata,
+ offer_amount
+ );
+ let return_coin =
+ swap(
+ pool_obj,
+ offer_coin,
+ return_coin_metadata,
+ min_return_amount
+ );
+ primary_fungible_store::deposit(signer::address_of(account), return_coin);
+}
+
+
+
+
+
+
+## Function `create_pool`
+
+
+
+public fun create_pool(creator: &signer, name: string::String, symbol: string::String, swap_fee_rate: bigdecimal::BigDecimal, coins: vector<fungible_asset::FungibleAsset>, ann: u64): fungible_asset::FungibleAsset
+
+
+
+
+##### Implementation
+
+
+public fun create_pool(
+ creator: &signer,
+ name: String,
+ symbol: String,
+ swap_fee_rate: BigDecimal,
coins: vector<FungibleAsset>,
- ann: u64,
+ ann: u64
): FungibleAsset acquires Pool, ModuleStore {
- let (_, timestamp) = block::get_block_info();
- let (mint_cap, burn_cap, freeze_cap, extend_ref) = coin::initialize_and_generate_extend_ref (
- creator,
- option::none(),
- name,
- symbol,
- 6,
- string::utf8(b""),
- string::utf8(b""),
+ assert!(
+ vector::length(&coins) >= 2,
+ error::invalid_argument(EN_COINS)
);
+ let (_, timestamp) = block::get_block_info();
+ let (mint_cap, burn_cap, freeze_cap, extend_ref) =
+ coin::initialize_and_generate_extend_ref(
+ creator,
+ option::none(),
+ name,
+ symbol,
+ 6,
+ string::utf8(b""),
+ string::utf8(b"")
+ );
let coin_metadata: vector<Object<Metadata>> = vector[];
let len = vector::length(&coins);
let i = 0;
while (i < len) {
let j = i + 1;
- let coin_metadata_i = fungible_asset::metadata_from_asset(vector::borrow(&coins, i));
+ let coin_metadata_i =
+ fungible_asset::metadata_from_asset(vector::borrow(&coins, i));
while (j < len) {
- let coin_metadata_j = fungible_asset::metadata_from_asset(vector::borrow(&coins, j));
- assert!(coin_metadata_i != coin_metadata_j, error::invalid_argument(ESAME_COIN_TYPE));
+ let coin_metadata_j =
+ fungible_asset::metadata_from_asset(vector::borrow(&coins, j));
+ assert!(
+ coin_metadata_i != coin_metadata_j,
+ error::invalid_argument(ESAME_COIN_TYPE)
+ );
j = j + 1;
};
vector::push_back(&mut coin_metadata, coin_metadata_i);
@@ -1108,57 +1463,58 @@ Return swap simulation result
};
assert!(
- decimal128::val(&swap_fee_rate) < MAX_FEE_RATE,
+ bigdecimal::le(swap_fee_rate, max_fee_rate()),
error::invalid_argument(EOUT_OF_SWAP_FEE_RATE_RANGE)
);
- let pair_signer = &object::generate_signer_for_extending(&extend_ref);
- let pair_address = signer::address_of(pair_signer);
- // transfer pair object's ownership to initia_std
- object::transfer_raw(creator, pair_address, @initia_std);
+ let pool_signer = &object::generate_signer_for_extending(&extend_ref);
+ let pool_address = signer::address_of(pool_signer);
+ // transfer pool object's ownership to initia_std
+ object::transfer_raw(creator, pool_address, @initia_std);
move_to(
- pair_signer,
+ pool_signer,
Pool {
extend_ref,
ann: Ann {
ann_before: ann,
ann_after: ann,
- timestamp_before: timestamp,
- timestamp_after: timestamp,
+ timestamp_before: timestamp,
+ timestamp_after: timestamp
},
swap_fee_rate,
coin_metadata,
burn_cap,
freeze_cap,
- mint_cap,
+ mint_cap
}
);
- let liquidity_token = provide_liquidity(
- object::address_to_object<Pool>(pair_address),
- coins,
- option::none(),
- );
+ let liquidity_token =
+ provide_liquidity(
+ object::address_to_object<Pool>(pool_address),
+ coins,
+ option::none()
+ );
// update module store
let module_store = borrow_global_mut<ModuleStore>(@initia_std);
- module_store.pair_count = module_store.pair_count + 1;
+ module_store.pool_count = module_store.pool_count + 1;
table::add(
- &mut module_store.pairs,
- pair_address,
- true,
+ &mut module_store.pools,
+ pool_address,
+ true
);
- // emit create pair event
- event::emit<CreatePairEvent>(
- CreatePairEvent {
+ // emit create pool event
+ event::emit<CreatePoolEvent>(
+ CreatePoolEvent {
coins: get_coin_addresses(coin_metadata),
- liquidity_token: pair_address,
+ liquidity_token: pool_address,
ann,
- swap_fee_rate,
- },
+ swap_fee_rate
+ }
);
return liquidity_token
@@ -1167,97 +1523,55 @@ Return swap simulation result
-
-
## Function `provide_liquidity`
-public fun provide_liquidity(pair: object::Object<stableswap::Pool>, coins: vector<fungible_asset::FungibleAsset>, min_liquidity: option::Option<u64>): fungible_asset::FungibleAsset
+public fun provide_liquidity(pool_obj: object::Object<stableswap::Pool>, coins: vector<fungible_asset::FungibleAsset>, min_liquidity: option::Option<u64>): fungible_asset::FungibleAsset
-
-Implementation
+##### Implementation
-public fun provide_liquidity(pair: Object<Pool>, coins: vector<FungibleAsset>, min_liquidity: Option<u64>): FungibleAsset acquires Pool {
- let pool = borrow_pool(pair);
- let pair_addr = object::object_address(pair);
+public fun provide_liquidity(
+ pool_obj: Object<Pool>, coins: vector<FungibleAsset>, min_liquidity: Option<u64>
+): FungibleAsset acquires Pool {
+ let pool = borrow_pool(pool_obj);
+ // check before simaultion
let n = check_coin_metadata(&pool.coin_metadata, &coins);
- let ann = get_current_ann(&pool.ann);
-
- let pool_amounts_before = get_pool_amounts(pair_addr, pool.coin_metadata);
- let d_before = get_d(pool_amounts_before, ann);
- let total_supply = option::extract(&mut fungible_asset::supply(pair));
let amounts = get_amounts(&coins);
-
- // pool amounts before adjust fee
- let pool_amounts_after: vector<u64> = vector[];
- let i = 0;
- while (i < n) {
- let pool_amount = *vector::borrow(&pool_amounts_before, i);
- let offer_amount = *vector::borrow(&amounts, i);
- if (total_supply == 0) {
- assert!(offer_amount > 0, error::invalid_argument(EZERO_LIQUIDITY));
- };
- vector::push_back(&mut pool_amounts_after, pool_amount + offer_amount);
- i = i + 1;
- };
-
- let d_ideal = get_d(pool_amounts_after, ann);
-
- // calc fees
- let liquidity_amount = if (total_supply > 0) {
- let provide_fee_rate = decimal128::new(
- decimal128::val(&pool.swap_fee_rate) * (n as u128) / (4 * (n - 1) as u128)
- );
- i = 0;
- while (i < n) {
- let pool_amount_before = *vector::borrow(&pool_amounts_before, i);
- let pool_amount_after = vector::borrow_mut(&mut pool_amounts_after, i);
- let ideal_balance = mul_div_u64(d_ideal, pool_amount_before, d_before);
- let diff = if (ideal_balance > *pool_amount_after) {
- ideal_balance - *pool_amount_after
- } else {
- *pool_amount_after - ideal_balance
- };
- let fee = decimal128::mul_u64(&provide_fee_rate, diff);
- *pool_amount_after = *pool_amount_after - fee;
- i = i + 1;
- };
-
- let d_real = get_d(pool_amounts_after, ann);
- (mul_div_u128(total_supply, (d_real - d_before as u128), (d_before as u128)) as u64)
- } else {
- d_ideal
- };
+ let (liquidity_amount, fee_amounts) = provide_simulation(pool_obj, amounts);
assert!(
- option::is_none(&min_liquidity) || *option::borrow(&min_liquidity) <= liquidity_amount,
- error::invalid_state(EMIN_LIQUIDITY),
+ option::is_none(&min_liquidity)
+ || *option::borrow(&min_liquidity) <= liquidity_amount,
+ error::invalid_state(EMIN_LIQUIDITY)
);
- i = 0;
+ let pool_addr = object::object_address(&pool_obj);
+ let i = 0;
while (i < n) {
let fa = vector::pop_back(&mut coins);
- primary_fungible_store::deposit(pair_addr, fa);
+ primary_fungible_store::deposit(pool_addr, fa);
i = i + 1;
};
vector::destroy_empty(coins);
+ let pool = borrow_pool(pool_obj);
let liquidity_token = coin::mint(&pool.mint_cap, liquidity_amount);
event::emit<ProvideEvent>(
ProvideEvent {
coins: get_coin_addresses(pool.coin_metadata),
coin_amounts: amounts,
- liquidity_token: pair_addr,
- liquidity: liquidity_amount,
- },
+ fee_amounts,
+ liquidity_token: pool_addr,
+ liquidity: liquidity_amount
+ }
);
return liquidity_token
@@ -1266,8 +1580,6 @@ Return swap simulation result
-
-
## Function `withdraw_liquidity`
@@ -1279,50 +1591,75 @@ Return swap simulation result
-
-Implementation
+##### Implementation
-public fun withdraw_liquidity(liquidity_token: FungibleAsset, min_return_amounts: vector<Option<u64>>): vector<FungibleAsset> acquires Pool {
- let pair_addr = object::object_address(fungible_asset::metadata_from_asset(&liquidity_token));
- let pair = object::address_to_object<Pool>(pair_addr);
+public fun withdraw_liquidity(
+ liquidity_token: FungibleAsset, min_return_amounts: vector<Option<u64>>
+): vector<FungibleAsset> acquires Pool {
+ let pool_addr =
+ object::object_address(
+ &fungible_asset::metadata_from_asset(&liquidity_token)
+ );
+ let pool_obj = object::address_to_object<Pool>(pool_addr);
let liquidity_amount = fungible_asset::amount(&liquidity_token);
- assert!(liquidity_amount != 0, error::invalid_argument(EZERO_LIQUIDITY));
- let pool = borrow_pool(pair);
- let pair_signer = object::generate_signer_for_extending(&pool.extend_ref);
- let total_supply = option::extract(&mut fungible_asset::supply(pair));
+ assert!(
+ liquidity_amount != 0,
+ error::invalid_argument(EZERO_LIQUIDITY)
+ );
+ let pool = borrow_pool(pool_obj);
+ let pool_signer = object::generate_signer_for_extending(&pool.extend_ref);
+ let total_supply = option::extract(&mut fungible_asset::supply(pool_obj));
let n = vector::length(&pool.coin_metadata);
let return_coins: vector<FungibleAsset> = vector[];
- let pool_amounts = get_pool_amounts(pair_addr, pool.coin_metadata);
+ let pool_amounts = get_pool_amounts(pool_addr, pool.coin_metadata);
let coin_amounts: vector<u64> = vector[];
+ let fee_amounts: vector<u64> = vector[];
let i = 0;
while (i < n) {
+ vector::push_back(&mut fee_amounts, 0);
let pool_amount = *vector::borrow(&pool_amounts, i);
- let return_amount = (mul_div_u128((pool_amount as u128), (liquidity_amount as u128), total_supply) as u64);
+ let return_amount =
+ (
+ mul_div_u128(
+ (pool_amount as u128),
+ (liquidity_amount as u128),
+ total_supply
+ ) as u64
+ );
let min_return = vector::borrow(&min_return_amounts, i);
let coin_metadata = *vector::borrow(&pool.coin_metadata, i);
assert!(
- option::is_none(min_return) || *option::borrow(min_return) <= return_amount,
- error::invalid_state(EMIN_WITHDRAW),
+ option::is_none(min_return)
+ || *option::borrow(min_return) <= return_amount,
+ error::invalid_state(EMIN_WITHDRAW)
);
vector::push_back(&mut coin_amounts, return_amount);
- vector::push_back(&mut return_coins, primary_fungible_store::withdraw(&pair_signer, coin_metadata, return_amount));
+ vector::push_back(
+ &mut return_coins,
+ primary_fungible_store::withdraw(
+ &pool_signer,
+ coin_metadata,
+ return_amount
+ )
+ );
i = i + 1;
};
coin::burn(&pool.burn_cap, liquidity_token);
- event::emit<ProvideEvent>(
- ProvideEvent {
+ event::emit<WithdrawEvent>(
+ WithdrawEvent {
coins: get_coin_addresses(pool.coin_metadata),
coin_amounts,
- liquidity_token: pair_addr,
- liquidity: liquidity_amount,
- },
+ fee_amounts,
+ liquidity_token: pool_addr,
+ liquidity: liquidity_amount
+ }
);
return return_coins
@@ -1331,569 +1668,516 @@ Return swap simulation result
-
+
-
-
-## Function `swap`
+## Function `single_asset_withdraw_liquidity`
-public fun swap(pair: object::Object<stableswap::Pool>, offer_coin: fungible_asset::FungibleAsset, return_coin_metadata: object::Object<fungible_asset::Metadata>, min_return_amount: option::Option<u64>): fungible_asset::FungibleAsset
+public fun single_asset_withdraw_liquidity(liquidity_token: fungible_asset::FungibleAsset, return_coin_metadata: object::Object<fungible_asset::Metadata>, min_return_amount: option::Option<u64>): fungible_asset::FungibleAsset
-
-Implementation
+##### Implementation
-public fun swap(pair: Object<Pool>, offer_coin: FungibleAsset, return_coin_metadata: Object<Metadata>, min_return_amount: Option<u64>): FungibleAsset acquires Pool {
- let offer_coin_metadata = fungible_asset::metadata_from_asset(&offer_coin);
- let offer_amount = fungible_asset::amount(&offer_coin);
- let (return_amount, fee_amount) = swap_simulation(pair, offer_coin_metadata, return_coin_metadata, offer_amount);
- return_amount = return_amount - fee_amount;
-
+public fun single_asset_withdraw_liquidity(
+ liquidity_token: FungibleAsset,
+ return_coin_metadata: Object<Metadata>,
+ min_return_amount: Option<u64>
+): FungibleAsset acquires Pool {
+ // get pool infos
+ let pool_addr =
+ object::object_address(
+ &fungible_asset::metadata_from_asset(&liquidity_token)
+ );
+ let pool_obj = object::address_to_object<Pool>(pool_addr);
+ let liquidity_amount = fungible_asset::amount(&liquidity_token);
assert!(
- option::is_none(&min_return_amount) || *option::borrow(&min_return_amount) <= return_amount,
- error::invalid_state(EMIN_RETURN),
+ liquidity_amount != 0,
+ error::invalid_argument(EZERO_LIQUIDITY)
);
- let pool = borrow_pool(pair);
- let pair_addr = object::object_address(pair);
- let pair_signer = object::generate_signer_for_extending(&pool.extend_ref);
- primary_fungible_store::deposit(pair_addr, offer_coin);
- let return_coin = primary_fungible_store::withdraw(&pair_signer, return_coin_metadata, return_amount);
+ let pool = borrow_pool(pool_obj);
+ let pool_signer = object::generate_signer_for_extending(&pool.extend_ref);
+ let n = vector::length(&pool.coin_metadata);
- event::emit<SwapEvent>(
- SwapEvent {
- offer_coin: object::object_address(offer_coin_metadata),
- return_coin: object::object_address(return_coin_metadata),
- liquidity_token: pair_addr,
- fee_amount,
- offer_amount,
- return_amount,
- },
+ // get return index
+ let (found, return_index) = vector::index_of(
+ &pool.coin_metadata, &return_coin_metadata
+ );
+ assert!(found, error::invalid_argument(ECOIN_TYPE));
+
+ // calculate amount of returning asset
+ let (return_amount, fee) =
+ single_asset_withdraw_simulation(
+ pool_obj,
+ liquidity_amount,
+ return_index
+ );
+ assert!(
+ option::is_none(&min_return_amount)
+ || *option::borrow(&min_return_amount) <= return_amount,
+ error::invalid_state(EMIN_RETURN)
);
- return return_coin
-}
-
-
-
-
-
-
-
-
-## Function `pool_info`
-
-
-
-public fun pool_info(pair: object::Object<stableswap::Pool>): (vector<object::Object<fungible_asset::Metadata>>, vector<u64>, u64, decimal128::Decimal128)
-
-
-
-
-
-Implementation
+ // withdraw return coin
+ let return_coin =
+ primary_fungible_store::withdraw(
+ &pool_signer,
+ return_coin_metadata,
+ return_amount
+ );
+ // burn liquidity token
+ let pool = borrow_pool(pool_obj);
+ coin::burn(&pool.burn_cap, liquidity_token);
-public fun pool_info(pair: Object<Pool>): (vector<Object<Metadata>>, vector<u64>, u64, Decimal128) acquires Pool {
- let pair_addr = object::object_address(pair);
- let pool = borrow_global<Pool>(pair_addr);
+ // generate withdraw/fee amounts for event
+ let coin_amounts: vector<u64> = vector[];
+ let fee_amounts: vector<u64> = vector[];
+ let i = 0;
+ while (i < n) {
+ let (amount, fee) = if (i == return_index) {
+ (return_amount, fee)
+ } else { (0, 0) };
+ vector::push_back(&mut coin_amounts, amount);
+ vector::push_back(&mut fee_amounts, fee);
+ i = i + 1;
+ };
- let ann = get_current_ann(&pool.ann);
- let pool_amounts = get_pool_amounts(pair_addr, pool.coin_metadata);
+ // emit withdraw event
+ event::emit<WithdrawEvent>(
+ WithdrawEvent {
+ coins: get_coin_addresses(pool.coin_metadata),
+ coin_amounts,
+ fee_amounts,
+ liquidity_token: pool_addr,
+ liquidity: liquidity_amount
+ }
+ );
- (
- pool.coin_metadata,
- pool_amounts,
- ann,
- pool.swap_fee_rate,
- )
+ return_coin
}
-
-
-
-
-## Function `borrow_pool`
-
-
-
-fun borrow_pool(pair: object::Object<stableswap::Pool>): &stableswap::Pool
-
-
+
+## Function `swap`
-
-Implementation
-inline fun borrow_pool(pair: Object<Pool>): &Pool {
- borrow_global<Pool>(object::object_address(pair))
-}
+public fun swap(pool_obj: object::Object<stableswap::Pool>, offer_coin: fungible_asset::FungibleAsset, return_coin_metadata: object::Object<fungible_asset::Metadata>, min_return_amount: option::Option<u64>): fungible_asset::FungibleAsset
-
+##### Implementation
-
-
-## Function `borrow_pool_mut`
-
-
-
-fun borrow_pool_mut(pair: object::Object<stableswap::Pool>): &mut stableswap::Pool
-
+public fun swap(
+ pool_obj: Object<Pool>,
+ offer_coin: FungibleAsset,
+ return_coin_metadata: Object<Metadata>,
+ min_return_amount: Option<u64>
+): FungibleAsset acquires Pool {
+ let offer_coin_metadata = fungible_asset::metadata_from_asset(&offer_coin);
+ let offer_amount = fungible_asset::amount(&offer_coin);
+ let (return_amount, fee_amount) =
+ swap_simulation(
+ pool_obj,
+ offer_coin_metadata,
+ return_coin_metadata,
+ offer_amount,
+ true
+ );
+ return_amount = return_amount - fee_amount;
+ assert!(
+ option::is_none(&min_return_amount)
+ || *option::borrow(&min_return_amount) <= return_amount,
+ error::invalid_state(EMIN_RETURN)
+ );
-
-Implementation
+ let pool = borrow_pool(pool_obj);
+ let pool_addr = object::object_address(&pool_obj);
+ let pool_signer = object::generate_signer_for_extending(&pool.extend_ref);
+ primary_fungible_store::deposit(pool_addr, offer_coin);
+ let return_coin =
+ primary_fungible_store::withdraw(
+ &pool_signer,
+ return_coin_metadata,
+ return_amount
+ );
+ event::emit<SwapEvent>(
+ SwapEvent {
+ offer_coin: object::object_address(&offer_coin_metadata),
+ return_coin: object::object_address(&return_coin_metadata),
+ liquidity_token: pool_addr,
+ fee_amount,
+ offer_amount,
+ return_amount
+ }
+ );
-inline fun borrow_pool_mut(pair: Object<Pool>): &mut Pool {
- borrow_global_mut<Pool>(object::object_address(pair))
+ return return_coin
}
-
-
-
+
-## Function `get_current_ann`
+## Function `pool_info`
-fun get_current_ann(ann: &stableswap::Ann): u64
+public fun pool_info(pool_obj: object::Object<stableswap::Pool>): (vector<object::Object<fungible_asset::Metadata>>, vector<u64>, u64, bigdecimal::BigDecimal)
-
-Implementation
+##### Implementation
-fun get_current_ann(ann: &Ann): u64 {
- let (_, timestamp) = block::get_block_info();
+public fun pool_info(
+ pool_obj: Object<Pool>
+): (vector<Object<Metadata>>, vector<u64>, u64, BigDecimal) acquires Pool {
+ let pool_addr = object::object_address(&pool_obj);
+ let pool = borrow_global<Pool>(pool_addr);
- if (timestamp >= ann.timestamp_after) {
- return ann.ann_after
- };
+ let ann = get_current_ann(&pool.ann);
+ let pool_amounts = get_pool_amounts(pool_addr, pool.coin_metadata);
- if (ann.ann_after > ann.ann_before) {
- return ann.ann_before + (ann.ann_after - ann.ann_before) * (timestamp - ann.timestamp_before) / (ann.timestamp_after - ann.timestamp_before)
- } else {
- return ann.ann_before - (ann.ann_before - ann.ann_after) * (timestamp - ann.timestamp_before) / (ann.timestamp_after - ann.timestamp_before)
- }
+ (pool.coin_metadata, pool_amounts, ann, pool.swap_fee_rate)
}
-
-
-
-
-## Function `check_coin_metadata`
-
-
-
-fun check_coin_metadata(coin_metadata: &vector<object::Object<fungible_asset::Metadata>>, coins: &vector<fungible_asset::FungibleAsset>): u64
-
-
-
-
-
-Implementation
+
+## Function `single_asset_withdraw_simulation`
-fun check_coin_metadata(coin_metadata: &vector<Object<Metadata>>, coins: &vector<FungibleAsset>): u64 {
- let len = vector::length(coin_metadata);
- assert!(len == vector::length(coins), error::invalid_argument(EN_COINS));
- let i = 0;
- while (i < len) {
- let metadata = vector::borrow(coin_metadata, i);
- let metadata_ = fungible_asset::metadata_from_asset(vector::borrow(coins, i));
- assert!(*metadata == metadata_, error::invalid_argument(ECOIN_TYPE));
- i = i + 1;
- };
- return len
-}
+public fun single_asset_withdraw_simulation(pool_obj: object::Object<stableswap::Pool>, liquidity_amount: u64, return_index: u64): (u64, u64)
-
+##### Implementation
-
-## Function `get_pool_amounts`
-
-
-
-fun get_pool_amounts(pair_addr: address, coin_metadata: vector<object::Object<fungible_asset::Metadata>>): vector<u64>
-
-
-
-
-
-Implementation
+public fun single_asset_withdraw_simulation(
+ pool_obj: Object<Pool>, liquidity_amount: u64, return_index: u64
+): (u64, u64) acquires Pool {
+ let pool_addr = object::object_address(&pool_obj);
+ let pool = borrow_global<Pool>(pool_addr);
+ let n = vector::length(&pool.coin_metadata);
+ let ann = get_current_ann(&pool.ann);
+ let withdraw_fee_rate =
+ bigdecimal::div_by_u64(
+ bigdecimal::mul_by_u64(pool.swap_fee_rate, n),
+ 4 * (n - 1)
+ );
+ let total_supply = option::extract(&mut fungible_asset::supply(pool_obj));
+ let pool_amounts = get_pool_amounts(pool_addr, pool.coin_metadata);
+ let d_before = get_d(pool_amounts, ann);
+ let d_after =
+ d_before
+ - (
+ mul_div_u128(
+ (liquidity_amount as u128),
+ (d_before as u128),
+ total_supply
+ ) as u64
+ );
+
+ let y_without_fee = get_y_with_given_d(
+ pool_amounts,
+ return_index,
+ ann,
+ d_after
+ );
+ let return_amount_without_fee =
+ *vector::borrow(&pool_amounts, return_index) - y_without_fee;
+ // calculate fee
-fun get_pool_amounts(pair_addr: address, coin_metadata: vector<Object<Metadata>>): vector<u64> {
- let amounts: vector<u64> = vector[];
- let len = vector::length(&coin_metadata);
+ // amount that after fee removed
+ let pool_amounts_reduced = pool_amounts;
let i = 0;
- while(i < len) {
- let metadata = *vector::borrow(&coin_metadata, i);
- vector::push_back(&mut amounts, primary_fungible_store::balance(pair_addr, metadata));
- i = i + 1;
- };
-
- return amounts
-}
-
-
-
-
-
-
-
-
-## Function `get_amounts`
-
-
-
-fun get_amounts(coins: &vector<fungible_asset::FungibleAsset>): vector<u64>
-
-
-
-
-
-Implementation
-
+ while (i < n) {
+ // get difference with ideal amount
+ let amount_diff =
+ if (i == return_index) {
+ mul_div_u64(
+ *vector::borrow(&pool_amounts, i),
+ d_after,
+ d_before
+ ) - y_without_fee
+ } else {
+ *vector::borrow(&pool_amounts, i)
+ - mul_div_u64(
+ *vector::borrow(&pool_amounts, i),
+ d_after,
+ d_before
+ )
+ };
-fun get_amounts(coins: &vector<FungibleAsset>): vector<u64> {
- let amounts: vector<u64> = vector[];
- let len = vector::length(coins);
- let i = 0;
- while(i < len) {
- let amount = fungible_asset::amount(vector::borrow(coins, i));
- vector::push_back(&mut amounts, amount);
+ let pool_amount = vector::borrow_mut(&mut pool_amounts_reduced, i);
+ *pool_amount = *pool_amount
+ - bigdecimal::mul_by_u64_truncate(withdraw_fee_rate, amount_diff);
i = i + 1;
};
- return amounts
-}
-
-
-
-
-
-
-
-
-## Function `get_coin_addresses`
-
-
-
-fun get_coin_addresses(coin_metadata: vector<object::Object<fungible_asset::Metadata>>): vector<address>
-
-
-
-
-
-Implementation
-
-
-fun get_coin_addresses(coin_metadata: vector<Object<Metadata>>): vector<address> {
- let addresses: vector<address> = vector[];
- let len = vector::length(&coin_metadata);
- let i = 0;
- while(i < len) {
- let addr = object::object_address(*vector::borrow(&coin_metadata, i));
- vector::push_back(&mut addresses, addr);
- i = i + 1;
- };
+ let return_amount =
+ *vector::borrow(&pool_amounts_reduced, return_index)
+ - get_y_with_given_d(
+ pool_amounts_reduced,
+ return_index,
+ ann,
+ d_after
+ ) - 1; // sub 1 in case of rounding errors
- return addresses
+ (return_amount, return_amount_without_fee - return_amount)
}
-
+
-
+## Function `imbalance_withdraw_simulation`
-## Function `get_d`
-
-fun get_d(amounts: vector<u64>, ann: u64): u64
+public fun imbalance_withdraw_simulation(pool_obj: object::Object<stableswap::Pool>, coin_amounts: vector<u64>, max_liquidity_amount: option::Option<u64>): (u64, vector<u64>)
-
-Implementation
-
+##### Implementation
-fun get_d(amounts: vector<u64>, ann: u64): u64 {
- let ann = (ann as u256);
- let sum: u256 = 0;
- let n = (vector::length(&amounts) as u256);
- let i = 0;
- while (i < (n as u64)) {
- sum = sum + (*vector::borrow(&amounts, i) as u256);
- i = i + 1;
- };
- if (sum == 0) return 0;
- let d = sum;
+public fun imbalance_withdraw_simulation(
+ pool_obj: Object<Pool>,
+ coin_amounts: vector<u64>,
+ max_liquidity_amount: Option<u64>
+): (u64, vector<u64>) acquires Pool {
+ let pool_addr = object::object_address(&pool_obj);
+ let pool = borrow_global<Pool>(pool_addr);
+ let n = vector::length(&pool.coin_metadata);
+ let ann = get_current_ann(&pool.ann);
+ let withdraw_fee_rate =
+ bigdecimal::div_by_u64(
+ bigdecimal::mul_by_u64(pool.swap_fee_rate, n),
+ 4 * (n - 1)
+ );
+ let total_supply = option::extract(&mut fungible_asset::supply(pool_obj));
- let i = 0;
+ assert!(
+ n == vector::length(&coin_amounts),
+ error::invalid_argument(EN_COINS)
+ );
- // converge
- // d = (ann * sum - d_prod) / (ann - 1)
- while (i < 255) {
- let d_prev = d;
- // D ** (n + 1) / (n ** n * prod)
- let d_prod = d;
- let j = 0;
- while (j < (n as u64)) {
- d_prod = d_prod * d / (n as u256) / (*vector::borrow(&amounts, j) as u256);
- j = j + 1;
- };
+ let pool_amounts_before = get_pool_amounts(pool_addr, pool.coin_metadata);
+ let pool_amounts_after = copy pool_amounts_before;
+ let d_before = get_d(pool_amounts_before, ann);
- d = (ann * sum / A_PRECISION + d_prod * n) * d / ((ann - A_PRECISION) * d / A_PRECISION + (n + 1) * d_prod);
- if (d > d_prev) {
- if (d - d_prev <= 1) break
- } else {
- if (d_prev - d <= 1) break
- };
+ // update pool amounts after withdraw
+ let i = 0;
+ while (i < n) {
+ let pool_amount = vector::borrow_mut(&mut pool_amounts_after, i);
+ let withdraw_amount = *vector::borrow(&coin_amounts, i);
+ *pool_amount = *pool_amount - withdraw_amount;
i = i + 1;
};
- return (d as u64)
-}
-
-
-
-
-
-
-
-
-## Function `get_y`
+ let d_after_without_fee = get_d(pool_amounts_after, ann);
-get counterparty's amount
+ let fees: vector<u64> = vector[];
-
-fun get_y(offer_index: u64, return_index: u64, offer_amount: u64, pool_amounts: vector<u64>, ann: u64): u64
-
-
-
-
-
-Implementation
-
-
-fun get_y(offer_index: u64, return_index: u64, offer_amount: u64, pool_amounts: vector<u64>, ann: u64): u64 {
- let d = (get_d(pool_amounts, ann) as u256);
-
- let ann = (ann as u256);
- // Done by solving quadratic equation iteratively.
- // x_1**2 + x_1 * (sum' - (A*n**n - 1) * D / (A * n**n)) = D ** (n + 1) / (n ** (2 * n) * prod' * A)
- // y**2 + b*y = c
-
- // y = (y**2 + c) / (2*y + b)
- let n = vector::length(&pool_amounts);
+ // calculate fee
let i = 0;
- let sum = 0; // sum'
- let c = d;
while (i < n) {
- if (i == return_index) {
- i = i + 1;
- continue
- };
-
- let pool_amount = if (i == offer_index) {
- (*vector::borrow(&pool_amounts, i) + offer_amount as u256)
- } else {
- (*vector::borrow(&pool_amounts, i) as u256)
- };
-
- sum = sum + pool_amount;
- c = c * d / (pool_amount * (n as u256));
+ let ideal_balance =
+ mul_div_u64(
+ *vector::borrow(&pool_amounts_before, i),
+ d_after_without_fee,
+ d_before
+ );
+ let balance_after = vector::borrow_mut(&mut pool_amounts_after, i);
+ let amount_diff =
+ if (*balance_after > ideal_balance) {
+ *balance_after - ideal_balance
+ } else {
+ ideal_balance - *balance_after
+ };
+ let fee = bigdecimal::mul_by_u64_ceil(withdraw_fee_rate, amount_diff);
+ vector::push_back(&mut fees, fee);
+ *balance_after = *balance_after - fee; // to get d_after remove fee
i = i + 1;
};
- c = c * d * A_PRECISION / ann / (n as u256);
- let b_plus_d = sum + d * A_PRECISION / ann; // need to sub d but sub later due to value must be less than 0
-
- let y_prev;
- let y = d;
-
- let i = 0;
- // converge
- while (i < 255) {
- y_prev = y;
- y = (y * y + c) / (2 * y + b_plus_d - d); // sub d here
+ let d_after = get_d(pool_amounts_after, ann);
+ let liquidity_amount =
+ (
+ mul_div_u128(
+ total_supply,
+ (d_before - d_after as u128),
+ (d_before as u128)
+ ) as u64
+ );
+ assert!(
+ liquidity_amount != 0,
+ error::invalid_state(EZERO_LIQUIDITY)
+ );
+ liquidity_amount = liquidity_amount + 1; // add 1 just in case of rounding errors
- if (y > y_prev) {
- if (y - y_prev <= 1) break
- } else {
- if (y_prev - y <= 1) break
- };
- i = i + 1;
- };
+ assert!(
+ option::is_none(&max_liquidity_amount)
+ || *option::borrow(&max_liquidity_amount) >= liquidity_amount,
+ error::invalid_state(EMAX_LIQUIDITY)
+ );
- (y as u64)
+ (liquidity_amount, fees)
}
-
-
## Function `swap_simulation`
-fun swap_simulation(pair: object::Object<stableswap::Pool>, offer_coin_metadata: object::Object<fungible_asset::Metadata>, return_coin_metadata: object::Object<fungible_asset::Metadata>, offer_amount: u64): (u64, u64)
+public fun swap_simulation(pool_obj: object::Object<stableswap::Pool>, offer_coin_metadata: object::Object<fungible_asset::Metadata>, return_coin_metadata: object::Object<fungible_asset::Metadata>, amount: u64, is_offer_amount: bool): (u64, u64)
-
-Implementation
+##### Implementation
-fun swap_simulation(
- pair: Object<Pool>,
+public fun swap_simulation(
+ pool_obj: Object<Pool>,
offer_coin_metadata: Object<Metadata>,
return_coin_metadata: Object<Metadata>,
- offer_amount: u64,
+ amount: u64,
+ is_offer_amount: bool
): (u64, u64) acquires Pool {
- let pool = borrow_pool(pair);
- let pair_addr = object::object_address(pair);
- let n = vector::length(&pool.coin_metadata);
-
- let ann = get_current_ann(&pool.ann);
- let pool_amounts = get_pool_amounts(pair_addr, pool.coin_metadata);
- let offer_index = n;
- let return_index = n;
- let i = 0;
- while (i < n) {
- let metadata = *vector::borrow(&pool.coin_metadata, i);
- if (metadata == offer_coin_metadata){
- offer_index = i
- };
- if (metadata == return_coin_metadata){
- return_index = i
- };
- if (offer_index != n && return_index != n) {
- break
- };
- i = i + 1;
- };
-
- assert!(offer_index != n && return_index != n, error::invalid_argument(ECOIN_TYPE));
-
- let y = get_y(offer_index, return_index, offer_amount, pool_amounts, ann);
- let return_amount = *vector::borrow(&pool_amounts, return_index) - y - 1; // sub 1 just in case
- let fee_amount = decimal128::mul_u64(&pool.swap_fee_rate, return_amount);
- (return_amount, fee_amount)
-}
-
-
-
-
-
-
-
-
-## Function `mul_div_u64`
-
-
-
-fun mul_div_u64(a: u64, b: u64, c: u64): u64
-
-
-
-
-
-Implementation
-
-
-fun mul_div_u64(a: u64, b: u64, c: u64): u64 {
- return ((a as u128) * (b as u128) / (c as u128) as u64)
+ let pool = borrow_pool(pool_obj);
+ let pool_addr = object::object_address(&pool_obj);
+ let pool_amounts = get_pool_amounts(pool_addr, pool.coin_metadata);
+ swap_simulation_with_given_amounts(
+ pool_obj,
+ pool_amounts,
+ offer_coin_metadata,
+ return_coin_metadata,
+ amount,
+ is_offer_amount
+ )
}
-
-
-
-
-## Function `mul_div_u128`
-
-
-
-fun mul_div_u128(a: u128, b: u128, c: u128): u128
-
+
+## Function `provide_simulation`
-
-Implementation
-
-fun mul_div_u128(a: u128, b: u128, c: u128): u128 {
- return ((a as u256) * (b as u256) / (c as u256) as u128)
-}
+public fun provide_simulation(pool_obj: object::Object<stableswap::Pool>, amounts: vector<u64>): (u64, vector<u64>)
-
-
-
+##### Implementation
-## Function `check_chain_permission`
-
-Check signer is chain
+public fun provide_simulation(
+ pool_obj: Object<Pool>, amounts: vector<u64>
+): (u64, vector<u64>) acquires Pool {
+ let pool = borrow_pool(pool_obj);
+ let pool_addr = object::object_address(&pool_obj);
+ let ann = get_current_ann(&pool.ann);
-fun check_chain_permission(chain: &signer)
-
+ let pool_amounts_before = get_pool_amounts(pool_addr, pool.coin_metadata);
+ let d_before = get_d(pool_amounts_before, ann);
+ let total_supply = option::extract(&mut fungible_asset::supply(pool_obj));
+ let n = vector::length(&amounts);
+ // pool amounts before adjust fee
+ let pool_amounts_after: vector<u64> = vector[];
+ let i = 0;
+ while (i < n) {
+ let pool_amount = *vector::borrow(&pool_amounts_before, i);
+ let offer_amount = *vector::borrow(&amounts, i);
+ if (total_supply == 0) {
+ assert!(
+ offer_amount > 0,
+ error::invalid_argument(EZERO_LIQUIDITY)
+ );
+ };
+ vector::push_back(
+ &mut pool_amounts_after,
+ pool_amount + offer_amount
+ );
+ i = i + 1;
+ };
+ let d_ideal = get_d(pool_amounts_after, ann);
+ let fee_amounts: vector<u64> = vector[];
-
-Implementation
+ // calc fees
+ let liquidity_amount =
+ if (total_supply > 0) {
+ let provide_fee_rate =
+ bigdecimal::div_by_u64(
+ bigdecimal::mul_by_u64(pool.swap_fee_rate, n),
+ 4 * (n - 1)
+ );
+ i = 0;
+ while (i < n) {
+ let pool_amount_before = *vector::borrow(&pool_amounts_before, i);
+ let pool_amount_after = vector::borrow_mut(&mut pool_amounts_after, i);
+ let ideal_balance = mul_div_u64(
+ d_ideal,
+ pool_amount_before,
+ d_before
+ );
+ let diff =
+ if (ideal_balance > *pool_amount_after) {
+ ideal_balance - *pool_amount_after
+ } else {
+ *pool_amount_after - ideal_balance
+ };
+ let fee = bigdecimal::mul_by_u64_ceil(provide_fee_rate, diff);
+ vector::push_back(&mut fee_amounts, fee);
+ *pool_amount_after = *pool_amount_after - fee;
+ i = i + 1;
+ };
+ let d_real = get_d(pool_amounts_after, ann);
+ (
+ mul_div_u128(
+ total_supply,
+ (d_real - d_before as u128),
+ (d_before as u128)
+ ) as u64
+ )
+ } else {
+ d_ideal
+ };
-fun check_chain_permission(chain: &signer) {
- assert!(signer::address_of(chain) == @initia_std, error::permission_denied(EUNAUTHORIZED));
+ (liquidity_amount, fee_amounts)
}
-
-
-
-
diff --git a/initia_stdlib/doc/staking.md b/initia_stdlib/doc/staking.md
index ebd6cb8..fbfc515 100644
--- a/initia_stdlib/doc/staking.md
+++ b/initia_stdlib/doc/staking.md
@@ -20,13 +20,6 @@
- [Struct `UnbondingResponse`](#0x1_staking_UnbondingResponse)
- [Constants](#@Constants_0)
- [Function `reward_metadata`](#0x1_staking_reward_metadata)
-- [Function `init_module`](#0x1_staking_init_module)
-- [Function `load_staking_state`](#0x1_staking_load_staking_state)
-- [Function `load_staking_state_mut`](#0x1_staking_load_staking_state_mut)
-- [Function `load_delegation`](#0x1_staking_load_delegation)
-- [Function `load_delegation_mut`](#0x1_staking_load_delegation_mut)
-- [Function `load_unbonding`](#0x1_staking_load_unbonding)
-- [Function `load_unbonding_mut`](#0x1_staking_load_unbonding_mut)
- [Function `get_delegation_response_from_delegation`](#0x1_staking_get_delegation_response_from_delegation)
- [Function `get_unbonding_response_from_unbonding`](#0x1_staking_get_unbonding_response_from_unbonding)
- [Function `get_delegation`](#0x1_staking_get_delegation)
@@ -41,7 +34,6 @@
- [Function `get_validator_from_unbonding_response`](#0x1_staking_get_validator_from_unbonding_response)
- [Function `get_release_time_from_unbonding_response`](#0x1_staking_get_release_time_from_unbonding_response)
- [Function `get_unbonding_amount_from_unbonding_response`](#0x1_staking_get_unbonding_amount_from_unbonding_response)
-- [Function `check_chain_permission`](#0x1_staking_check_chain_permission)
- [Function `initialize_for_chain`](#0x1_staking_initialize_for_chain)
- [Function `slash_unbonding_for_chain`](#0x1_staking_slash_unbonding_for_chain)
- [Function `deposit_unbonding_coin_for_chain`](#0x1_staking_deposit_unbonding_coin_for_chain)
@@ -55,7 +47,6 @@
- [Function `claim_unbonding_script`](#0x1_staking_claim_unbonding_script)
- [Function `claim_reward_script`](#0x1_staking_claim_reward_script)
- [Function `claim_reward`](#0x1_staking_claim_reward)
-- [Function `calculate_reward`](#0x1_staking_calculate_reward)
- [Function `empty_delegation`](#0x1_staking_empty_delegation)
- [Function `get_metadata_from_delegation`](#0x1_staking_get_metadata_from_delegation)
- [Function `get_validator_from_delegation`](#0x1_staking_get_validator_from_delegation)
@@ -65,9 +56,6 @@
- [Function `withdraw_delegation`](#0x1_staking_withdraw_delegation)
- [Function `extract_delegation`](#0x1_staking_extract_delegation)
- [Function `merge_delegation`](#0x1_staking_merge_delegation)
-- [Function `destroy_delegation_and_extract_reward`](#0x1_staking_destroy_delegation_and_extract_reward)
-- [Function `unbonding_share_from_amount`](#0x1_staking_unbonding_share_from_amount)
-- [Function `unbonding_amount_from_share`](#0x1_staking_unbonding_amount_from_share)
- [Function `empty_unbonding`](#0x1_staking_empty_unbonding)
- [Function `get_metadata_from_unbonding`](#0x1_staking_get_metadata_from_unbonding)
- [Function `get_validator_from_unbonding`](#0x1_staking_get_validator_from_unbonding)
@@ -80,17 +68,15 @@
- [Function `extract_unbonding`](#0x1_staking_extract_unbonding)
- [Function `merge_unbonding`](#0x1_staking_merge_unbonding)
- [Function `claim_unbonding`](#0x1_staking_claim_unbonding)
-- [Function `delegate_internal`](#0x1_staking_delegate_internal)
-- [Function `undelegate_internal`](#0x1_staking_undelegate_internal)
- [Function `share_to_amount`](#0x1_staking_share_to_amount)
- [Function `amount_to_share`](#0x1_staking_amount_to_share)
use 0x1::account;
+use 0x1::bigdecimal;
use 0x1::block;
use 0x1::coin;
use 0x1::cosmos;
-use 0x1::decimal128;
use 0x1::error;
use 0x1::event;
use 0x1::fungible_asset;
@@ -115,8 +101,7 @@
-
-Fields
+##### Fields
@@ -129,8 +114,6 @@
-
-
## Struct `StakingState`
@@ -142,8 +125,7 @@
-
-Fields
+##### Fields
@@ -160,19 +142,19 @@
-
-
total_share: u128
+total_share: bigdecimal::BigDecimal
-
-
-
unbonding_share: u128
+unbonding_share: bigdecimal::BigDecimal
-
-
-
reward_index: decimal128::Decimal128
+reward_index: bigdecimal::BigDecimal
-
@@ -204,8 +186,6 @@
-
-
## Struct `Delegation`
@@ -218,8 +198,7 @@ Define a delegation entry which can be transferred.
-
-Fields
+##### Fields
@@ -236,13 +215,13 @@ Define a delegation entry which can be transferred.
-
-
share: u64
+share: bigdecimal::BigDecimal
-
-
-
reward_index: decimal128::Decimal128
+reward_index: bigdecimal::BigDecimal
-
@@ -250,8 +229,6 @@ Define a delegation entry which can be transferred.
-
-
## Struct `Unbonding`
@@ -264,8 +241,7 @@ Define a unbonding entry which can be transferred.
-
-Fields
+##### Fields
@@ -282,7 +258,7 @@ Define a unbonding entry which can be transferred.
-
-
unbonding_share: u64
+unbonding_share: bigdecimal::BigDecimal
-
@@ -296,8 +272,6 @@ Define a unbonding entry which can be transferred.
-
-
## Resource `DelegationStore`
@@ -311,8 +285,7 @@ These are kept in a single resource to ensure locality of data.
-
-Fields
+##### Fields
@@ -331,8 +304,6 @@ These are kept in a single resource to ensure locality of data.
-
-
## Struct `UnbondingKey`
@@ -345,8 +316,7 @@ Key for Unbonding
-
-Fields
+##### Fields
@@ -365,8 +335,6 @@ Key for Unbonding
-
-
## Struct `RewardEvent`
@@ -380,8 +348,7 @@ Event emitted when some amount of reward is claimed by entry function.
-
-Fields
+##### Fields
@@ -406,8 +373,6 @@ Event emitted when some amount of reward is claimed by entry function.
-
-
## Struct `DelegationDepositEvent`
@@ -421,8 +386,7 @@ Event emitted when a Delegation is deposited to an account.
-
-Fields
+##### Fields
@@ -445,7 +409,7 @@ Event emitted when a Delegation is deposited to an account.
-
-
share: u64
+share: bigdecimal::BigDecimal
-
@@ -453,8 +417,6 @@ Event emitted when a Delegation is deposited to an account.
-
-
## Struct `DelegationWithdrawEvent`
@@ -468,8 +430,7 @@ Event emitted when a Delegation is withdrawn from an account.
-
-Fields
+##### Fields
@@ -492,7 +453,7 @@ Event emitted when a Delegation is withdrawn from an account.
-
-
share: u64
+share: bigdecimal::BigDecimal
-
@@ -500,8 +461,6 @@ Event emitted when a Delegation is withdrawn from an account.
-
-
## Struct `UnbondingDepositEvent`
@@ -515,8 +474,7 @@ Event emitted when a Unbonding is deposited from an account.
-
-Fields
+##### Fields
@@ -539,7 +497,7 @@ Event emitted when a Unbonding is deposited from an account.
-
-
share: u64
+share: bigdecimal::BigDecimal
-
@@ -553,8 +511,6 @@ Event emitted when a Unbonding is deposited from an account.
-
-
## Struct `UnbondingWithdrawEvent`
@@ -568,8 +524,7 @@ Event emitted when a Unbonding is withdrawn from an account.
-
-Fields
+##### Fields
@@ -592,7 +547,7 @@ Event emitted when a Unbonding is withdrawn from an account.
-
-
share: u64
+share: bigdecimal::BigDecimal
-
@@ -606,8 +561,6 @@ Event emitted when a Unbonding is withdrawn from an account.
-
-
## Struct `DelegationResponse`
@@ -619,8 +572,7 @@ Event emitted when a Unbonding is withdrawn from an account.
-
-Fields
+##### Fields
@@ -637,7 +589,7 @@ Event emitted when a Unbonding is withdrawn from an account.
-
-
share: u64
+share: bigdecimal::BigDecimal
-
@@ -651,8 +603,6 @@ Event emitted when a Unbonding is withdrawn from an account.
-
-
## Struct `UnbondingResponse`
@@ -664,8 +614,7 @@ Event emitted when a Unbonding is withdrawn from an account.
-
-Fields
+##### Fields
@@ -696,8 +645,6 @@ Event emitted when a Unbonding is withdrawn from an account.
-
-
## Constants
@@ -723,6 +670,16 @@ Max number of view function response items.
+
+
+release_time
of the source_unbonding
must be sooner than or equal to the one of dst_unbonding
+
+
+const ERELEASE_TIME: u64 = 9;
+
+
+
+
Can not find delegation
@@ -813,16 +770,6 @@ Can not claim before release_time
-
-
-release_time
of the source_unbonding
must be sooner than or equal to the one of dst_unbonding
-
-
-const ERELEASE_TIME: u64 = 9;
-
-
-
-
Chain already has StakingState
for the given metadata
@@ -893,8 +840,7 @@ Validator of delegation which is used as operand doesn't match the other operand
-
-Implementation
+##### Implementation
public fun reward_metadata(): Object<Metadata> {
@@ -904,204 +850,6 @@ Validator of delegation which is used as operand doesn't match the other operand
-
-
-
-
-## Function `init_module`
-
-
-
-fun init_module(chain: &signer)
-
-
-
-
-
-Implementation
-
-
-fun init_module(chain: &signer) {
- move_to(chain, ModuleStore {
- staking_states: table::new(),
- });
-}
-
-
-
-
-
-
-
-
-## Function `load_staking_state`
-
-
-
-fun load_staking_state(staking_states: &table::Table<object::Object<fungible_asset::Metadata>, table::Table<string::String, staking::StakingState>>, metadata: object::Object<fungible_asset::Metadata>, validator: string::String): &staking::StakingState
-
-
-
-
-
-Implementation
-
-
-fun load_staking_state (staking_states: &Table<Object<Metadata>, Table<String, StakingState>>, metadata: Object<Metadata>, validator: String): &StakingState {
- assert!(table::contains(staking_states, metadata), error::not_found(ESTAKING_STATE_NOT_EXISTS));
- let states = table::borrow(staking_states, metadata);
-
- assert!(table::contains(states, validator), error::not_found(ESTAKING_STATE_NOT_EXISTS));
- table::borrow(states, validator)
-}
-
-
-
-
-
-
-
-
-## Function `load_staking_state_mut`
-
-
-
-fun load_staking_state_mut(staking_states: &mut table::Table<object::Object<fungible_asset::Metadata>, table::Table<string::String, staking::StakingState>>, metadata: object::Object<fungible_asset::Metadata>, validator: string::String): &mut staking::StakingState
-
-
-
-
-
-Implementation
-
-
-fun load_staking_state_mut (staking_states: &mut Table<Object<Metadata>, Table<String, StakingState>>, metadata: Object<Metadata>, validator: String): &mut StakingState {
- assert!(table::contains(staking_states, metadata), error::not_found(ESTAKING_STATE_NOT_EXISTS));
- let states = table::borrow_mut(staking_states, metadata);
-
- assert!(table::contains(states, validator), error::not_found(ESTAKING_STATE_NOT_EXISTS));
- table::borrow_mut(states, validator)
-}
-
-
-
-
-
-
-
-
-## Function `load_delegation`
-
-
-
-fun load_delegation(delegations: &table::Table<object::Object<fungible_asset::Metadata>, table::Table<string::String, staking::Delegation>>, metadata: object::Object<fungible_asset::Metadata>, validator: string::String): &staking::Delegation
-
-
-
-
-
-Implementation
-
-
-fun load_delegation (delegations: &Table<Object<Metadata>, Table<String, Delegation>>, metadata: Object<Metadata>, validator: String): &Delegation {
- assert!(table::contains(delegations, metadata), error::not_found(EDELEGATION_NOT_FOUND));
- let delegations = table::borrow(delegations, metadata);
-
- assert!(table::contains(delegations, validator), error::not_found(EDELEGATION_NOT_FOUND));
- table::borrow(delegations, validator)
-}
-
-
-
-
-
-
-
-
-## Function `load_delegation_mut`
-
-
-
-fun load_delegation_mut(delegations: &mut table::Table<object::Object<fungible_asset::Metadata>, table::Table<string::String, staking::Delegation>>, metadata: object::Object<fungible_asset::Metadata>, validator: string::String): &mut staking::Delegation
-
-
-
-
-
-Implementation
-
-
-fun load_delegation_mut (delegations: &mut Table<Object<Metadata>, Table<String, Delegation>>, metadata: Object<Metadata>, validator: String): &mut Delegation {
- assert!(table::contains(delegations, metadata), error::not_found(EDELEGATION_NOT_FOUND));
- let delegations = table::borrow_mut(delegations, metadata);
-
- assert!(table::contains(delegations, validator), error::not_found(EDELEGATION_NOT_FOUND));
- table::borrow_mut(delegations, validator)
-}
-
-
-
-
-
-
-
-
-## Function `load_unbonding`
-
-
-
-fun load_unbonding(unbondings: &table::Table<object::Object<fungible_asset::Metadata>, table::Table<staking::UnbondingKey, staking::Unbonding>>, metadata: object::Object<fungible_asset::Metadata>, validator: string::String, release_time: u64): &staking::Unbonding
-
-
-
-
-
-Implementation
-
-
-fun load_unbonding (unbondings: &Table<Object<Metadata>, Table<UnbondingKey, Unbonding>>, metadata: Object<Metadata>, validator: String, release_time: u64): &Unbonding {
- assert!(table::contains(unbondings, metadata), error::not_found(EUNBONDING_NOT_FOUND));
- let unbondings = table::borrow(unbondings, metadata);
-
- let key = UnbondingKey { validator, release_time };
- assert!(table::contains(unbondings, key), error::not_found(EUNBONDING_NOT_FOUND));
- table::borrow(unbondings, key)
-}
-
-
-
-
-
-
-
-
-## Function `load_unbonding_mut`
-
-
-
-fun load_unbonding_mut(unbondings: &mut table::Table<object::Object<fungible_asset::Metadata>, table::Table<staking::UnbondingKey, staking::Unbonding>>, metadata: object::Object<fungible_asset::Metadata>, validator: string::String, release_time: u64): &mut staking::Unbonding
-
-
-
-
-
-Implementation
-
-
-fun load_unbonding_mut (unbondings: &mut Table<Object<Metadata>, Table<UnbondingKey, Unbonding>>, metadata: Object<Metadata>, validator: String, release_time: u64): &mut Unbonding {
- assert!(table::contains(unbondings, metadata), error::not_found(EUNBONDING_NOT_FOUND));
- let unbondings = table::borrow_mut(unbondings, metadata);
-
- let key = UnbondingKey { validator, release_time };
- assert!(table::contains(unbondings, key), error::not_found(EUNBONDING_NOT_FOUND));
- table::borrow_mut(unbondings, key)
-}
-
-
-
-
-
-
## Function `get_delegation_response_from_delegation`
@@ -1114,16 +862,21 @@ util function to convert Delegation => DelegationResponse for third party querie
-
-Implementation
+##### Implementation
-public fun get_delegation_response_from_delegation(delegation: &Delegation): DelegationResponse acquires ModuleStore {
+public fun get_delegation_response_from_delegation(
+ delegation: &Delegation
+): DelegationResponse acquires ModuleStore {
let metadata = delegation.metadata;
let validator = delegation.validator;
let module_store = borrow_global<ModuleStore>(@initia_std);
- let state = load_staking_state(&module_store.staking_states, metadata, validator);
+ let state = load_staking_state(
+ &module_store.staking_states,
+ metadata,
+ validator
+ );
let reward = calculate_reward(delegation, state);
@@ -1131,15 +884,13 @@ util function to convert Delegation => DelegationResponse for third party querie
metadata: delegation.metadata,
validator: delegation.validator,
share: delegation.share,
- unclaimed_reward: reward,
+ unclaimed_reward: reward
}
}
-
-
## Function `get_unbonding_response_from_unbonding`
@@ -1152,26 +903,25 @@ util function to convert Unbonding => UnbondingResponse for third party queriers
-
-Implementation
+##### Implementation
-public fun get_unbonding_response_from_unbonding(unbonding: &Unbonding): UnbondingResponse acquires ModuleStore{
+public fun get_unbonding_response_from_unbonding(
+ unbonding: &Unbonding
+): UnbondingResponse acquires ModuleStore {
let unbonding_amount = get_unbonding_amount_from_unbonding(unbonding);
UnbondingResponse {
metadata: unbonding.metadata,
validator: unbonding.validator,
unbonding_amount,
- release_time: unbonding.release_time,
+ release_time: unbonding.release_time
}
}
-
-
## Function `get_delegation`
@@ -1185,25 +935,31 @@ Get delegation info of specifed addr and validator
-
-Implementation
+##### Implementation
public fun get_delegation(
- addr: address,
- metadata: Object<Metadata>,
- validator: String,
+ addr: address, metadata: Object<Metadata>, validator: String
): DelegationResponse acquires DelegationStore, ModuleStore {
assert!(
is_account_registered(addr),
- error::not_found(EDELEGATION_STORE_NOT_EXISTS),
+ error::not_found(EDELEGATION_STORE_NOT_EXISTS)
);
let delegation_store = borrow_global<DelegationStore>(addr);
- let delegation = load_delegation(&delegation_store.delegations, metadata, validator);
+ let delegation =
+ load_delegation(
+ &delegation_store.delegations,
+ metadata,
+ validator
+ );
let module_store = borrow_global<ModuleStore>(@initia_std);
- let state = load_staking_state(&module_store.staking_states, metadata, validator);
+ let state = load_staking_state(
+ &module_store.staking_states,
+ metadata,
+ validator
+ );
let reward = calculate_reward(delegation, state);
@@ -1211,15 +967,13 @@ Get delegation info of specifed addr and validator
metadata,
validator,
share: delegation.share,
- unclaimed_reward: reward,
+ unclaimed_reward: reward
}
}
-
-
## Function `get_delegations`
@@ -1233,15 +987,14 @@ Get all delegation info of an addr
-
-Implementation
+##### Implementation
public fun get_delegations(
addr: address,
metadata: Object<Metadata>,
start_after: Option<String>,
- limit: u8,
+ limit: u8
): vector<DelegationResponse> acquires DelegationStore, ModuleStore {
if (limit > MAX_LIMIT) {
limit = MAX_LIMIT;
@@ -1249,7 +1002,7 @@ Get all delegation info of an addr
assert!(
is_account_registered(addr),
- error::not_found(EDELEGATION_STORE_NOT_EXISTS),
+ error::not_found(EDELEGATION_STORE_NOT_EXISTS)
);
let module_store = borrow_global<ModuleStore>(@initia_std);
@@ -1261,13 +1014,13 @@ Get all delegation info of an addr
delegations,
option::none(),
start_after,
- 2,
+ 2
);
- let prepare = table::prepare(&mut delegations_iter);
+ let prepare = table::prepare(delegations_iter);
let res: vector<DelegationResponse> = vector[];
while (vector::length(&res) < (limit as u64) && prepare) {
- let (validator, delegation) = table::next(&mut delegations_iter);
+ let (validator, delegation) = table::next(delegations_iter);
let state = table::borrow(staking_states, validator);
let reward = calculate_reward(delegation, state);
vector::push_back(
@@ -1276,10 +1029,10 @@ Get all delegation info of an addr
metadata: delegation.metadata,
validator: delegation.validator,
share: delegation.share,
- unclaimed_reward: reward,
- },
+ unclaimed_reward: reward
+ }
);
- prepare = table::prepare(&mut delegations_iter);
+ prepare = table::prepare(delegations_iter);
};
res
@@ -1288,8 +1041,6 @@ Get all delegation info of an addr
-
-
## Function `get_unbonding`
@@ -1303,39 +1054,42 @@ Get unbonding info of (addr, metadata, validator, release time)
-
-Implementation
+##### Implementation
public fun get_unbonding(
addr: address,
metadata: Object<Metadata>,
validator: String,
- release_time: u64,
+ release_time: u64
): UnbondingResponse acquires DelegationStore, ModuleStore {
assert!(
is_account_registered(addr),
- error::not_found(EDELEGATION_STORE_NOT_EXISTS),
+ error::not_found(EDELEGATION_STORE_NOT_EXISTS)
);
let delegation_store = borrow_global<DelegationStore>(addr);
- let unbonding = load_unbonding(&delegation_store.unbondings, metadata, validator, release_time);
+ let unbonding =
+ load_unbonding(
+ &delegation_store.unbondings,
+ metadata,
+ validator,
+ release_time
+ );
let unbonding_amount = get_unbonding_amount_from_unbonding(unbonding);
UnbondingResponse {
metadata: unbonding.metadata,
validator: unbonding.validator,
unbonding_amount,
- release_time,
+ release_time
}
}
-
-
## Function `get_unbondings`
@@ -1349,8 +1103,7 @@ Get all unbondings of (addr, validator)
-
-Implementation
+##### Implementation
public fun get_unbondings(
@@ -1358,7 +1111,7 @@ Get all unbondings of (addr, validator)
metadata: Object<Metadata>,
start_after_validator: Option<String>,
start_after_release_time: Option<u64>,
- limit: u8,
+ limit: u8
): vector<UnbondingResponse> acquires DelegationStore, ModuleStore {
if (limit > MAX_LIMIT) {
limit = MAX_LIMIT;
@@ -1366,38 +1119,41 @@ Get all unbondings of (addr, validator)
assert!(
is_account_registered(addr),
- error::not_found(EDELEGATION_STORE_NOT_EXISTS),
+ error::not_found(EDELEGATION_STORE_NOT_EXISTS)
);
assert!(
- option::is_some(&start_after_validator) == option::is_some(&start_after_release_time),
+ option::is_some(&start_after_validator)
+ == option::is_some(&start_after_release_time),
error::invalid_argument(EINVALID_START_AFTER)
);
let delegation_store = borrow_global<DelegationStore>(addr);
let unbondings = table::borrow(&delegation_store.unbondings, metadata);
- let start_after = if (option::is_some(&start_after_validator)) {
- option::some(UnbondingKey {
- validator: *option::borrow(&start_after_validator),
- release_time: *option::borrow(&start_after_release_time),
- })
- } else {
- option::none()
- };
+ let start_after =
+ if (option::is_some(&start_after_validator)) {
+ option::some(
+ UnbondingKey {
+ validator: *option::borrow(&start_after_validator),
+ release_time: *option::borrow(&start_after_release_time)
+ }
+ )
+ } else {
+ option::none()
+ };
let unbondings_iter = table::iter(
unbondings,
option::none(),
start_after,
- 2,
+ 2
);
let res: vector<UnbondingResponse> = vector[];
- while (vector::length(&res) < (limit as u64) && table::prepare<UnbondingKey, Unbonding>(
- &mut unbondings_iter
- )) {
- let (_, unbonding) = table::next<UnbondingKey, Unbonding>(&mut unbondings_iter);
+ while (vector::length(&res) < (limit as u64)
+ && table::prepare<UnbondingKey, Unbonding>(unbondings_iter)) {
+ let (_, unbonding) = table::next<UnbondingKey, Unbonding>(unbondings_iter);
let unbonding_amount = get_unbonding_amount_from_unbonding(unbonding);
vector::push_back(
&mut res,
@@ -1405,8 +1161,8 @@ Get all unbondings of (addr, validator)
metadata: unbonding.metadata,
validator: unbonding.validator,
unbonding_amount,
- release_time: unbonding.release_time,
- },
+ release_time: unbonding.release_time
+ }
);
};
@@ -1416,8 +1172,6 @@ Get all unbondings of (addr, validator)
-
-
## Function `get_metadata_from_delegation_response`
@@ -1430,19 +1184,18 @@ get metadata
from get_metadata_from_delegation_response(delegation_res: &DelegationResponse): Object<Metadata> {
+public fun get_metadata_from_delegation_response(
+ delegation_res: &DelegationResponse
+): Object<Metadata> {
delegation_res.metadata
}
-
-
## Function `get_validator_from_delegation_response`
@@ -1455,19 +1208,18 @@ get validator
from get_validator_from_delegation_response(delegation_res: &DelegationResponse): String {
+public fun get_validator_from_delegation_response(
+ delegation_res: &DelegationResponse
+): String {
delegation_res.validator
}
-
-
## Function `get_share_from_delegation_response`
@@ -1475,24 +1227,23 @@ get validator
from DelegationResponse
-public fun get_share_from_delegation_response(delegation_res: &staking::DelegationResponse): u64
+public fun get_share_from_delegation_response(delegation_res: &staking::DelegationResponse): bigdecimal::BigDecimal
-
-Implementation
+##### Implementation
-public fun get_share_from_delegation_response(delegation_res: &DelegationResponse): u64 {
+public fun get_share_from_delegation_response(
+ delegation_res: &DelegationResponse
+): BigDecimal {
delegation_res.share
}
-
-
## Function `get_unclaimed_reward_from_delegation_response`
@@ -1505,19 +1256,18 @@ get unclaimed_reward
from get_unclaimed_reward_from_delegation_response(delegation_res: &DelegationResponse): u64 {
+public fun get_unclaimed_reward_from_delegation_response(
+ delegation_res: &DelegationResponse
+): u64 {
delegation_res.unclaimed_reward
}
-
-
## Function `get_metadata_from_unbonding_response`
@@ -1530,19 +1280,18 @@ get metadata
from get_metadata_from_unbonding_response(unbonding_res: &UnbondingResponse): Object<Metadata> {
+public fun get_metadata_from_unbonding_response(
+ unbonding_res: &UnbondingResponse
+): Object<Metadata> {
unbonding_res.metadata
}
-
-
## Function `get_validator_from_unbonding_response`
@@ -1555,19 +1304,18 @@ get validator
from get_validator_from_unbonding_response(unbonding_res: &UnbondingResponse): String {
+public fun get_validator_from_unbonding_response(
+ unbonding_res: &UnbondingResponse
+): String {
unbonding_res.validator
}
-
-
## Function `get_release_time_from_unbonding_response`
@@ -1580,19 +1328,18 @@ get release_time
from get_release_time_from_unbonding_response(unbonding_res: &UnbondingResponse): u64 {
+public fun get_release_time_from_unbonding_response(
+ unbonding_res: &UnbondingResponse
+): u64 {
unbonding_res.release_time
}
-
-
## Function `get_unbonding_amount_from_unbonding_response`
@@ -1605,44 +1352,18 @@ get unbonding_amount
from get_unbonding_amount_from_unbonding_response(unbonding_res: &UnbondingResponse): u64 {
+public fun get_unbonding_amount_from_unbonding_response(
+ unbonding_res: &UnbondingResponse
+): u64 {
unbonding_res.unbonding_amount
}
-
-
-
-
-## Function `check_chain_permission`
-
-Check signer is chain
-
-
-fun check_chain_permission(chain: &signer)
-
-
-
-
-
-Implementation
-
-
-fun check_chain_permission(chain: &signer) {
- assert!(signer::address_of(chain) == @initia_std, error::permission_denied(EUNAUTHORIZED_CHAIN_OPERATION));
-}
-
-
-
-
-
-
## Function `initialize_for_chain`
@@ -1655,24 +1376,33 @@ Initialize, Make staking store
-
-Implementation
+##### Implementation
-public entry fun initialize_for_chain(chain: &signer, metadata: Object<Metadata>) acquires ModuleStore {
+public entry fun initialize_for_chain(
+ chain: &signer, metadata: Object<Metadata>
+) acquires ModuleStore {
check_chain_permission(chain);
let module_store = borrow_global_mut<ModuleStore>(@initia_std);
- assert!(!table::contains(&module_store.staking_states, metadata), error::already_exists(ESTAKING_STATE_ALREADY_EXISTS));
- table::add(&mut module_store.staking_states, metadata, table::new());
+ assert!(
+ !table::contains(
+ &module_store.staking_states,
+ metadata
+ ),
+ error::already_exists(ESTAKING_STATE_ALREADY_EXISTS)
+ );
+ table::add(
+ &mut module_store.staking_states,
+ metadata,
+ table::new()
+ );
}
-
-
## Function `slash_unbonding_for_chain`
@@ -1680,49 +1410,62 @@ Initialize, Make staking store
Slash unbonding coin
-public entry fun slash_unbonding_for_chain(chain: &signer, metadata: object::Object<fungible_asset::Metadata>, validator: string::String, fraction: string::String)
+public entry fun slash_unbonding_for_chain(chain: &signer, metadata: object::Object<fungible_asset::Metadata>, validator: string::String, fraction: bigdecimal::BigDecimal)
-
-Implementation
+##### Implementation
public entry fun slash_unbonding_for_chain(
chain: &signer,
metadata: Object<Metadata>,
validator: String,
- fraction: String
+ fraction: BigDecimal
) acquires ModuleStore {
check_chain_permission(chain);
let module_store = borrow_global_mut<ModuleStore>(@initia_std);
- let state = load_staking_state_mut(&mut module_store.staking_states, metadata, validator);
-
- let fraction = decimal128::from_string(&fraction);
+ let state =
+ load_staking_state_mut(
+ &mut module_store.staking_states,
+ metadata,
+ validator
+ );
let unbonding_amount = fungible_asset::balance(state.unbonding_coin_store);
- let slash_amount = decimal128::mul_u64(&fraction, unbonding_amount);
+ let slash_amount = bigdecimal::mul_by_u64_truncate(fraction, unbonding_amount);
if (slash_amount > 0) {
- let unbonding_coin_store_signer = &object::generate_signer_for_extending(&state.unbonding_coin_store_ref);
- let slash_coin = fungible_asset::withdraw(unbonding_coin_store_signer, state.unbonding_coin_store, slash_amount);
+ let unbonding_coin_store_signer =
+ &object::generate_signer_for_extending(
+ &state.unbonding_coin_store_ref
+ );
+ let slash_coin =
+ fungible_asset::withdraw(
+ unbonding_coin_store_signer,
+ state.unbonding_coin_store,
+ slash_amount
+ );
// deposit to relayer for fund community pool
- coin::deposit(@relayer, slash_coin);
+ // relayer is module address, so we need to use sudo_deposit
+ coin::sudo_deposit(@relayer, slash_coin);
let staking_module = create_signer(@relayer);
// fund to community pool
- cosmos::fund_community_pool(&staking_module, metadata, slash_amount);
+ cosmos::fund_community_pool(
+ &staking_module,
+ metadata,
+ slash_amount
+ );
}
}
-
-
## Function `deposit_unbonding_coin_for_chain`
@@ -1735,8 +1478,7 @@ Deposit unbonding coin to global store
-
-Implementation
+##### Implementation
public entry fun deposit_unbonding_coin_for_chain(
@@ -1747,7 +1489,10 @@ Deposit unbonding coin to global store
) acquires ModuleStore {
check_chain_permission(chain);
- assert!(vector::length(&validators) == vector::length(&amounts), error::invalid_argument(ELENGTH_MISMATCH));
+ assert!(
+ vector::length(&validators) == vector::length(&amounts),
+ error::invalid_argument(ELENGTH_MISMATCH)
+ );
let module_store = borrow_global_mut<ModuleStore>(@initia_std);
let staking_module = create_signer(@relayer);
@@ -1755,21 +1500,34 @@ Deposit unbonding coin to global store
while (index < vector::length(&validators)) {
let validator = *vector::borrow(&validators, index);
let amount = *vector::borrow(&amounts, index);
- let state = load_staking_state_mut(&mut module_store.staking_states, metadata, validator);
+ let state =
+ load_staking_state_mut(
+ &mut module_store.staking_states,
+ metadata,
+ validator
+ );
// calculate share
- let total_unbonding_amount = fungible_asset::balance(state.unbonding_coin_store);
- let share_amount_ratio = if (total_unbonding_amount == 0) {
- decimal128::one()
- } else {
- decimal128::from_ratio(state.unbonding_share, (total_unbonding_amount as u128))
- };
-
- let share_diff = decimal128::mul_u64(&share_amount_ratio, amount);
- state.unbonding_share = state.unbonding_share + (share_diff as u128);
+ let total_unbonding_amount =
+ fungible_asset::balance(state.unbonding_coin_store);
+ let share_amount_ratio =
+ if (total_unbonding_amount == 0) {
+ bigdecimal::one()
+ } else {
+ bigdecimal::div_by_u64(state.unbonding_share, total_unbonding_amount)
+ };
+
+ let share_diff =
+ bigdecimal::mul(
+ share_amount_ratio, bigdecimal::from_ratio_u64(amount, 1)
+ );
+ state.unbonding_share = bigdecimal::add(state.unbonding_share, share_diff);
let unbonding_coin = coin::withdraw(&staking_module, metadata, amount);
- fungible_asset::deposit(state.unbonding_coin_store, unbonding_coin);
+ fungible_asset::deposit(
+ state.unbonding_coin_store,
+ unbonding_coin
+ );
index = index + 1;
}
@@ -1778,8 +1536,6 @@ Deposit unbonding coin to global store
-
-
## Function `deposit_reward_for_chain`
@@ -1792,19 +1548,21 @@ Deposit staking reward, and update reward_index
-
-Implementation
+##### Implementation
public entry fun deposit_reward_for_chain(
chain: &signer,
metadata: Object<Metadata>,
validators: vector<String>,
- reward_amounts: vector<u64>,
+ reward_amounts: vector<u64>
) acquires ModuleStore {
check_chain_permission(chain);
- assert!(vector::length(&validators) == vector::length(&reward_amounts), error::invalid_argument(ELENGTH_MISMATCH));
+ assert!(
+ vector::length(&validators) == vector::length(&reward_amounts),
+ error::invalid_argument(ELENGTH_MISMATCH)
+ );
let module_store = borrow_global_mut<ModuleStore>(@initia_std);
let staking_module = create_signer(@relayer);
let reward_metadata = reward_metadata();
@@ -1813,12 +1571,21 @@ Deposit staking reward, and update reward_index
while (index < vector::length(&validators)) {
let validator = *vector::borrow(&validators, index);
let reward_amount = *vector::borrow(&reward_amounts, index);
- let reward = coin::withdraw(&staking_module, reward_metadata, reward_amount);
+ let reward = coin::withdraw(
+ &staking_module,
+ reward_metadata,
+ reward_amount
+ );
- let state = load_staking_state_mut(&mut module_store.staking_states, metadata, validator);
- state.reward_index = decimal128::add(
- &state.reward_index,
- &decimal128::from_ratio((reward_amount as u128), state.total_share),
+ let state =
+ load_staking_state_mut(
+ &mut module_store.staking_states,
+ metadata,
+ validator
+ );
+ state.reward_index = bigdecimal::add(
+ state.reward_index,
+ bigdecimal::rev(bigdecimal::div_by_u64(state.total_share, reward_amount))
);
fungible_asset::deposit(state.reward_coin_store, reward);
@@ -1830,8 +1597,6 @@ Deposit staking reward, and update reward_index
-
-
## Function `is_account_registered`
@@ -1844,8 +1609,7 @@ Check the DelegationStore is already exist
-
-Implementation
+##### Implementation
public fun is_account_registered(account_addr: address): bool {
@@ -1855,8 +1619,6 @@ Check the DelegationStore is already exist
-
-
## Function `register`
@@ -1869,20 +1631,19 @@ Register an account delegation store
-
-Implementation
+##### Implementation
public entry fun register(account: &signer) {
let account_addr = signer::address_of(account);
assert!(
!is_account_registered(account_addr),
- error::already_exists(EDELEGATION_STORE_ALREADY_EXISTS),
+ error::already_exists(EDELEGATION_STORE_ALREADY_EXISTS)
);
let delegation_store = DelegationStore {
delegations: table::new<Object<Metadata>, Table<String, Delegation>>(),
- unbondings: table::new<Object<Metadata>, Table<UnbondingKey, Unbonding>>(),
+ unbondings: table::new<Object<Metadata>, Table<UnbondingKey, Unbonding>>()
};
move_to(account, delegation_store);
@@ -1891,8 +1652,6 @@ Register an account delegation store
-
-
## Function `delegate_script`
@@ -1905,15 +1664,14 @@ Delegate coin to a validator and deposit reward to signer.
-
-Implementation
+##### Implementation
public entry fun delegate_script(
account: &signer,
metadata: Object<Metadata>,
validator: String,
- amount: u64,
+ amount: u64
) acquires DelegationStore, ModuleStore {
let account_addr = signer::address_of(account);
if (!is_account_registered(account_addr)) {
@@ -1929,7 +1687,7 @@ Delegate coin to a validator and deposit reward to signer.
RewardEvent {
account: account_addr,
metadata,
- amount: fungible_asset::amount(&reward),
+ amount: fungible_asset::amount(&reward)
}
);
@@ -1939,8 +1697,6 @@ Delegate coin to a validator and deposit reward to signer.
-
-
## Function `delegate`
@@ -1953,64 +1709,92 @@ Delegate a fa to a validator.
-
-Implementation
+##### Implementation
public fun delegate(validator: String, fa: FungibleAsset): Delegation acquires ModuleStore {
let module_store = borrow_global_mut<ModuleStore>(@initia_std);
let metadata = fungible_asset::asset_metadata(&fa);
- assert!(table::contains(&module_store.staking_states, metadata), error::not_found(ESTAKING_STATE_NOT_EXISTS));
+ assert!(
+ table::contains(
+ &module_store.staking_states,
+ metadata
+ ),
+ error::not_found(ESTAKING_STATE_NOT_EXISTS)
+ );
let states = table::borrow_mut(&mut module_store.staking_states, metadata);
if (!table::contains(states, validator)) {
let reward_coin_store_ref = &object::create_object(@initia_std, false);
let unbonding_coin_store_ref = &object::create_object(@initia_std, false);
- let reward_coin_store_address = object::address_from_constructor_ref(reward_coin_store_ref);
- let reward_coin_store = primary_fungible_store::create_primary_store(reward_coin_store_address, reward_metadata());
+ let reward_coin_store_address =
+ object::address_from_constructor_ref(reward_coin_store_ref);
+ let reward_coin_store =
+ primary_fungible_store::create_primary_store(
+ reward_coin_store_address,
+ reward_metadata()
+ );
+
+ let unbonding_coin_store_address =
+ object::address_from_constructor_ref(unbonding_coin_store_ref);
+ let unbonding_coin_store =
+ primary_fungible_store::create_primary_store(
+ unbonding_coin_store_address,
+ metadata
+ );
- let unbonding_coin_store_address = object::address_from_constructor_ref(unbonding_coin_store_ref);
- let unbonding_coin_store = primary_fungible_store::create_primary_store(unbonding_coin_store_address, metadata);
-
- table::add (
+ table::add(
states,
validator,
StakingState {
metadata,
validator,
- total_share: 0,
- unbonding_share: 0,
- reward_index: decimal128::zero(),
- reward_coin_store_ref: object::generate_extend_ref(reward_coin_store_ref),
- unbonding_coin_store_ref: object::generate_extend_ref(unbonding_coin_store_ref),
+ total_share: bigdecimal::zero(),
+ unbonding_share: bigdecimal::zero(),
+ reward_index: bigdecimal::zero(),
+ reward_coin_store_ref: object::generate_extend_ref(
+ reward_coin_store_ref
+ ),
+ unbonding_coin_store_ref: object::generate_extend_ref(
+ unbonding_coin_store_ref
+ ),
reward_coin_store,
- unbonding_coin_store,
+ unbonding_coin_store
}
)
};
- let share_diff = delegate_internal(*string::bytes(&validator), &metadata, fungible_asset::amount(&fa));
- let state = load_staking_state_mut(&mut module_store.staking_states, metadata, validator);
- state.total_share = state.total_share + (share_diff as u128);
+ let share_diff =
+ delegate_internal(
+ *string::bytes(&validator),
+ &metadata,
+ fungible_asset::amount(&fa)
+ );
+ let state =
+ load_staking_state_mut(
+ &mut module_store.staking_states,
+ metadata,
+ validator
+ );
+ state.total_share = bigdecimal::add(state.total_share, share_diff);
// deposit to relayer
- coin::deposit(@relayer, fa);
+ // relayer is module address, so we need to use sudo_deposit
+ coin::sudo_deposit(@relayer, fa);
Delegation {
metadata,
validator,
share: share_diff,
- reward_index: state.reward_index,
+ reward_index: state.reward_index
}
}
-
-
## Function `undelegate_script`
@@ -2024,24 +1808,29 @@ unbonding amount can be slightly different with input amount due to round error.
-
-Implementation
+##### Implementation
public entry fun undelegate_script(
account: &signer,
metadata: Object<Metadata>,
validator: String,
- amount: u64,
+ amount: u64
) acquires DelegationStore, ModuleStore {
+
let account_addr = signer::address_of(account);
assert!(
is_account_registered(account_addr),
- error::not_found(EDELEGATION_STORE_NOT_EXISTS),
+ error::not_found(EDELEGATION_STORE_NOT_EXISTS)
+ );
+
+ let share = amount_to_share(
+ *string::bytes(&validator),
+ &metadata,
+ amount
);
- let share = amount_to_share(*string::bytes(&validator), &metadata, amount);
let delegation = withdraw_delegation(account, metadata, validator, share);
let (reward, unbonding) = undelegate(delegation);
@@ -2049,7 +1838,7 @@ unbonding amount can be slightly different with input amount due to round error.
RewardEvent {
account: account_addr,
metadata,
- amount: fungible_asset::amount(&reward),
+ amount: fungible_asset::amount(&reward)
}
);
@@ -2060,8 +1849,6 @@ unbonding amount can be slightly different with input amount due to round error.
-
-
## Function `undelegate`
@@ -2073,27 +1860,42 @@ unbonding amount can be slightly different with input amount due to round error.
-
-Implementation
+##### Implementation
-public fun undelegate(
- delegation: Delegation,
-): (FungibleAsset, Unbonding) acquires ModuleStore {
+public fun undelegate(delegation: Delegation): (FungibleAsset, Unbonding) acquires ModuleStore {
let share = delegation.share;
let validator = delegation.validator;
let metadata = delegation.metadata;
- let (unbonding_amount, release_time) = undelegate_internal(*string::bytes(&validator), &metadata, share);
+ let (unbonding_amount, release_time) =
+ undelegate_internal(
+ *string::bytes(&validator),
+ &metadata,
+ &share
+ );
let reward = destroy_delegation_and_extract_reward(delegation);
let module_store = borrow_global_mut<ModuleStore>(@initia_std);
- let state = load_staking_state_mut(&mut module_store.staking_states, metadata, validator);
+ let state =
+ load_staking_state_mut(
+ &mut module_store.staking_states,
+ metadata,
+ validator
+ );
- assert!(state.total_share >= (share as u128), error::invalid_state(EINSUFFICIENT_UNBONDING_DELEGATION_TOTAL_SHARE));
- state.total_share = state.total_share - (share as u128);
+ assert!(
+ bigdecimal::ge(state.total_share, share),
+ error::invalid_state(EINSUFFICIENT_UNBONDING_DELEGATION_TOTAL_SHARE)
+ );
+ state.total_share = bigdecimal::sub(state.total_share, share);
- let unbonding_share = unbonding_share_from_amount(metadata, validator, unbonding_amount);
+ let unbonding_share =
+ unbonding_share_from_amount(
+ metadata,
+ validator,
+ unbonding_amount
+ );
let unbonding = Unbonding { metadata, validator, unbonding_share, release_time };
(reward, unbonding)
@@ -2102,8 +1904,6 @@ unbonding amount can be slightly different with input amount due to round error.
-
-
## Function `claim_unbonding_script`
@@ -2116,8 +1916,7 @@ Claim unbonding_coin
from expired unbonding.
-
-Implementation
+##### Implementation
public entry fun claim_unbonding_script(
@@ -2130,12 +1929,24 @@ Claim unbonding_coin
from expired unbonding.
assert!(
is_account_registered(account_addr),
- error::not_found(EDELEGATION_STORE_NOT_EXISTS),
+ error::not_found(EDELEGATION_STORE_NOT_EXISTS)
);
// withdraw unbonding all
- let unbonding_info = get_unbonding(account_addr, metadata, validator, release_time);
- let unbonding = withdraw_unbonding(account, metadata, validator, release_time, unbonding_info.unbonding_amount);
+ let unbonding_info = get_unbonding(
+ account_addr,
+ metadata,
+ validator,
+ release_time
+ );
+ let unbonding =
+ withdraw_unbonding(
+ account,
+ metadata,
+ validator,
+ release_time,
+ unbonding_info.unbonding_amount
+ );
let unbonding_coin = claim_unbonding(unbonding);
coin::deposit(account_addr, unbonding_coin)
}
@@ -2143,8 +1954,6 @@ Claim unbonding_coin
from expired unbonding.
-
-
## Function `claim_reward_script`
@@ -2156,31 +1965,33 @@ Claim unbonding_coin
from expired unbonding.
-
-Implementation
+##### Implementation
public entry fun claim_reward_script(
- account: &signer,
- metadata: Object<Metadata>,
- validator: String
+ account: &signer, metadata: Object<Metadata>, validator: String
) acquires DelegationStore, ModuleStore {
let account_addr = signer::address_of(account);
assert!(
is_account_registered(account_addr),
- error::not_found(EDELEGATION_STORE_NOT_EXISTS),
+ error::not_found(EDELEGATION_STORE_NOT_EXISTS)
);
let delegation_store = borrow_global_mut<DelegationStore>(account_addr);
- let delegation = load_delegation_mut(&mut delegation_store.delegations, metadata, validator);
+ let delegation =
+ load_delegation_mut(
+ &mut delegation_store.delegations,
+ metadata,
+ validator
+ );
let reward = claim_reward(delegation);
event::emit(
RewardEvent {
account: account_addr,
metadata,
- amount: fungible_asset::amount(&reward),
+ amount: fungible_asset::amount(&reward)
}
);
@@ -2190,8 +2001,6 @@ Claim unbonding_coin
from expired unbonding.
-
-
## Function `claim_reward`
@@ -2204,26 +2013,35 @@ Claim staking reward from the specified validator.
-
-Implementation
+##### Implementation
-public fun claim_reward(
- delegation: &mut Delegation
-): FungibleAsset acquires ModuleStore {
+public fun claim_reward(delegation: &mut Delegation): FungibleAsset acquires ModuleStore {
let module_store = borrow_global_mut<ModuleStore>(@initia_std);
let metadata = delegation.metadata;
let validator = delegation.validator;
- let state = load_staking_state(&module_store.staking_states, metadata, validator);
+ let state = load_staking_state(
+ &module_store.staking_states,
+ metadata,
+ validator
+ );
let reward_amount = calculate_reward(delegation, state);
- let reward = if (reward_amount == 0) {
- fungible_asset::zero(reward_metadata())
- } else {
- let reward_coin_store_signer = &object::generate_signer_for_extending(&state.reward_coin_store_ref);
- fungible_asset::withdraw(reward_coin_store_signer, state.reward_coin_store, reward_amount)
- };
+ let reward =
+ if (reward_amount == 0) {
+ fungible_asset::zero(reward_metadata())
+ } else {
+ let reward_coin_store_signer =
+ &object::generate_signer_for_extending(
+ &state.reward_coin_store_ref
+ );
+ fungible_asset::withdraw(
+ reward_coin_store_signer,
+ state.reward_coin_store,
+ reward_amount
+ )
+ };
delegation.reward_index = state.reward_index;
@@ -2233,39 +2051,6 @@ Claim staking reward from the specified validator.
-
-
-
-
-## Function `calculate_reward`
-
-Calculate unclaimed reward
-
-
-fun calculate_reward(delegation: &staking::Delegation, state: &staking::StakingState): u64
-
-
-
-
-
-Implementation
-
-
-fun calculate_reward(delegation: &Delegation, state: &StakingState): u64 {
- assert!(
- delegation.metadata == state.metadata,
- error::invalid_argument(EMETADATA_MISMATCH),
- );
-
- let index_diff = decimal128::sub(&state.reward_index, &delegation.reward_index);
- decimal128::mul_u64(&index_diff, delegation.share)
-}
-
-
-
-
-
-
## Function `empty_delegation`
@@ -2279,24 +2064,23 @@ return empty delegation resource
-
-Implementation
+##### Implementation
-public fun empty_delegation(metadata: Object<Metadata>, validator: String): Delegation {
+public fun empty_delegation(
+ metadata: Object<Metadata>, validator: String
+): Delegation {
Delegation {
metadata,
validator,
- share: 0,
- reward_index: decimal128::zero(),
+ share: bigdecimal::zero(),
+ reward_index: bigdecimal::zero()
}
}
-
-
## Function `get_metadata_from_delegation`
@@ -2309,8 +2093,7 @@ Get metadata
from
-Implementation
+##### Implementation
public fun get_metadata_from_delegation(delegation: &Delegation): Object<Metadata> {
@@ -2320,8 +2103,6 @@ Get metadata
from
-
## Function `get_validator_from_delegation`
@@ -2334,8 +2115,7 @@ Get validator
from get_validator_from_delegation(delegation: &Delegation): String {
@@ -2345,8 +2125,6 @@ Get validator
from
## Function `get_share_from_delegation`
@@ -2354,24 +2132,21 @@ Get validator
from Delegation
-public fun get_share_from_delegation(delegation: &staking::Delegation): u64
+public fun get_share_from_delegation(delegation: &staking::Delegation): bigdecimal::BigDecimal
-
-Implementation
+##### Implementation
-public fun get_share_from_delegation(delegation: &Delegation): u64 {
+public fun get_share_from_delegation(delegation: &Delegation): BigDecimal {
delegation.share
}
-
-
## Function `destroy_empty_delegation`
@@ -2384,20 +2159,21 @@ Destory empty delegation
-
-Implementation
+##### Implementation
public fun destroy_empty_delegation(delegation: Delegation) {
- assert!(delegation.share == 0, error::invalid_argument(ENOT_EMPTY));
- let Delegation { metadata: _, validator: _, share: _, reward_index: _ } = delegation;
+ assert!(
+ bigdecimal::is_zero(delegation.share),
+ error::invalid_argument(ENOT_EMPTY)
+ );
+ let Delegation { metadata: _, validator: _, share: _, reward_index: _ } =
+ delegation;
}
-
-
## Function `deposit_delegation`
@@ -2410,17 +2186,15 @@ Deposit the delegation into recipient's account.
-
-Implementation
+##### Implementation
public fun deposit_delegation(
- account_addr: address,
- delegation: Delegation,
+ account_addr: address, delegation: Delegation
): FungibleAsset acquires DelegationStore, ModuleStore {
assert!(
is_account_registered(account_addr),
- error::not_found(EDELEGATION_STORE_NOT_EXISTS),
+ error::not_found(EDELEGATION_STORE_NOT_EXISTS)
);
let metadata = delegation.metadata;
@@ -2428,27 +2202,40 @@ Deposit the delegation into recipient's account.
let delegation_store = borrow_global_mut<DelegationStore>(account_addr);
if (!table::contains(&delegation_store.delegations, metadata)) {
- table::add(&mut delegation_store.delegations, metadata, table::new());
+ table::add(
+ &mut delegation_store.delegations,
+ metadata,
+ table::new()
+ );
};
let delegations = table::borrow_mut(&mut delegation_store.delegations, metadata);
if (!table::contains(delegations, validator)) {
table::add(
- delegations, validator,
- empty_delegation(delegation.metadata, delegation.validator),
+ delegations,
+ validator,
+ empty_delegation(
+ delegation.metadata,
+ delegation.validator
+ )
);
};
- event::emit (
+ event::emit(
DelegationDepositEvent {
account: account_addr,
metadata: delegation.metadata,
share: delegation.share,
- validator: delegation.validator,
+ validator: delegation.validator
}
);
- let dst_delegation = load_delegation_mut(&mut delegation_store.delegations, metadata, validator);
+ let dst_delegation =
+ load_delegation_mut(
+ &mut delegation_store.delegations,
+ metadata,
+ validator
+ );
merge_delegation(dst_delegation, delegation)
}
@@ -2456,8 +2243,6 @@ Deposit the delegation into recipient's account.
-
-
## Function `withdraw_delegation`
@@ -2465,43 +2250,46 @@ Deposit the delegation into recipient's account.
Withdraw specified share
from delegation.
-public fun withdraw_delegation(account: &signer, metadata: object::Object<fungible_asset::Metadata>, validator: string::String, share: u64): staking::Delegation
+public fun withdraw_delegation(account: &signer, metadata: object::Object<fungible_asset::Metadata>, validator: string::String, share: bigdecimal::BigDecimal): staking::Delegation
-
-Implementation
+##### Implementation
public fun withdraw_delegation(
account: &signer,
metadata: Object<Metadata>,
validator: String,
- share: u64,
+ share: BigDecimal
): Delegation acquires DelegationStore {
let account_addr = signer::address_of(account);
assert!(
is_account_registered(account_addr),
- error::not_found(EDELEGATION_STORE_NOT_EXISTS),
+ error::not_found(EDELEGATION_STORE_NOT_EXISTS)
);
let delegation_store = borrow_global_mut<DelegationStore>(account_addr);
- let delegation = load_delegation_mut(&mut delegation_store.delegations, metadata, validator);
+ let delegation =
+ load_delegation_mut(
+ &mut delegation_store.delegations,
+ metadata,
+ validator
+ );
event::emit(
- DelegationWithdrawEvent {
- account: account_addr,
- metadata,
- share,
- validator,
- }
+ DelegationWithdrawEvent { account: account_addr, metadata, share, validator }
);
// If withdraw all, remove delegation
if (delegation.share == share) {
- let delegations = table::borrow_mut(&mut delegation_store.delegations, metadata);
+ let delegations =
+ table::borrow_mut(
+ &mut delegation_store.delegations,
+ metadata
+ );
table::remove(delegations, validator)
// Else extract
} else {
@@ -2512,8 +2300,6 @@ Withdraw specified share
from delegation.
-
-
## Function `extract_delegation`
@@ -2521,33 +2307,35 @@ Withdraw specified share
from delegation.
Extracts specified share of delegatiion from the passed-in delegation
.
-public fun extract_delegation(delegation: &mut staking::Delegation, share: u64): staking::Delegation
+public fun extract_delegation(delegation: &mut staking::Delegation, share: bigdecimal::BigDecimal): staking::Delegation
-
-Implementation
+##### Implementation
-public fun extract_delegation(delegation: &mut Delegation, share: u64): Delegation {
- assert!(delegation.share >= share, error::invalid_argument(EINSUFFICIENT_AMOUNT));
+public fun extract_delegation(
+ delegation: &mut Delegation, share: BigDecimal
+): Delegation {
+ assert!(
+ bigdecimal::ge(delegation.share, share),
+ error::invalid_argument(EINSUFFICIENT_AMOUNT)
+ );
// Total share is invariant and reward_indexes are same btw given and new one so no need to update `reward_index`.
- delegation.share = delegation.share - share;
+ delegation.share = bigdecimal::sub(delegation.share, share);
Delegation {
metadata: delegation.metadata,
validator: delegation.validator,
reward_index: delegation.reward_index,
- share,
+ share
}
}
-
-
## Function `merge_delegation`
@@ -2561,30 +2349,26 @@ to the sum of the two shares (dst_delegation
and source_deleg
-
-Implementation
+##### Implementation
public fun merge_delegation(
- dst_delegation: &mut Delegation,
- source_delegation: Delegation
+ dst_delegation: &mut Delegation, source_delegation: Delegation
): FungibleAsset acquires ModuleStore {
assert!(
dst_delegation.metadata == source_delegation.metadata,
- error::invalid_argument(EMETADATA_MISMATCH),
+ error::invalid_argument(EMETADATA_MISMATCH)
);
assert!(
dst_delegation.validator == source_delegation.validator,
- error::invalid_argument(EVALIDATOR_MISMATCH),
+ error::invalid_argument(EVALIDATOR_MISMATCH)
);
- spec {
- assume dst_delegation.share + source_delegation.share <= MAX_U64;
- };
-
let reward = claim_reward(dst_delegation);
- dst_delegation.share = dst_delegation.share + source_delegation.share;
+ dst_delegation.share = bigdecimal::add(
+ dst_delegation.share, source_delegation.share
+ );
let source_reward = destroy_delegation_and_extract_reward(source_delegation);
fungible_asset::merge(&mut reward, source_reward);
@@ -2595,121 +2379,6 @@ to the sum of the two shares (dst_delegation
and source_deleg
-
-
-
-
-## Function `destroy_delegation_and_extract_reward`
-
-Destroy delegation and extract reward from delegation
-
-
-fun destroy_delegation_and_extract_reward(delegation: staking::Delegation): fungible_asset::FungibleAsset
-
-
-
-
-
-Implementation
-
-
-fun destroy_delegation_and_extract_reward (
- delegation: Delegation
-): FungibleAsset acquires ModuleStore {
- let metadata = delegation.metadata;
- let validator = delegation.validator;
-
- let module_store = borrow_global_mut<ModuleStore>(@initia_std);
- let state = load_staking_state(&module_store.staking_states, metadata, validator);
-
- let reward_amount = calculate_reward(&delegation, state);
- let reward = if (reward_amount == 0) {
- fungible_asset::zero(reward_metadata())
- } else {
- let reward_coin_store_signer = &object::generate_signer_for_extending(&state.reward_coin_store_ref);
- fungible_asset::withdraw(reward_coin_store_signer, state.reward_coin_store, reward_amount)
- };
-
- let Delegation { metadata: _, share: _, validator: _, reward_index: _ } = delegation;
-
- reward
-}
-
-
-
-
-
-
-
-
-## Function `unbonding_share_from_amount`
-
-For unbonding object
-
-
-
-fun unbonding_share_from_amount(metadata: object::Object<fungible_asset::Metadata>, validator: string::String, unbonding_amount: u64): u64
-
-
-
-
-
-Implementation
-
-
-fun unbonding_share_from_amount(metadata: Object<Metadata>, validator: String, unbonding_amount: u64): u64 acquires ModuleStore {
- let module_store = borrow_global_mut<ModuleStore>(@initia_std);
- let state = load_staking_state(&module_store.staking_states, metadata, validator);
-
- let total_unbonding_amount = fungible_asset::balance(state.unbonding_coin_store);
- let share_amount_ratio = if (total_unbonding_amount == 0) {
- decimal128::one()
- } else {
- decimal128::from_ratio(state.unbonding_share, (total_unbonding_amount as u128))
- };
-
- decimal128::mul_u64(&share_amount_ratio, unbonding_amount)
-}
-
-
-
-
-
-
-
-
-## Function `unbonding_amount_from_share`
-
-
-
-fun unbonding_amount_from_share(metadata: object::Object<fungible_asset::Metadata>, validator: string::String, unbonding_share: u64): u64
-
-
-
-
-
-Implementation
-
-
-fun unbonding_amount_from_share(metadata: Object<Metadata>, validator: String, unbonding_share: u64): u64 acquires ModuleStore {
- let module_store = borrow_global<ModuleStore>(@initia_std);
- let state = load_staking_state(&module_store.staking_states, metadata, validator);
-
- let total_unbonding_amount = fungible_asset::balance(state.unbonding_coin_store);
- let amount_share_ratio = if (state.unbonding_share == 0) {
- decimal128::one()
- } else {
- decimal128::from_ratio((total_unbonding_amount as u128), state.unbonding_share)
- };
-
- decimal128::mul_u64(&amount_share_ratio, unbonding_share)
-}
-
-
-
-
-
-
## Function `empty_unbonding`
@@ -2722,24 +2391,23 @@ return empty unbonding resource
-
-Implementation
+##### Implementation
-public fun empty_unbonding(metadata: Object<Metadata>, validator: String, release_time: u64): Unbonding {
+public fun empty_unbonding(
+ metadata: Object<Metadata>, validator: String, release_time: u64
+): Unbonding {
Unbonding {
metadata,
validator,
- unbonding_share: 0,
- release_time,
+ unbonding_share: bigdecimal::zero(),
+ release_time
}
}
-
-
## Function `get_metadata_from_unbonding`
@@ -2752,8 +2420,7 @@ Get metadata
from
-
-Implementation
+##### Implementation
public fun get_metadata_from_unbonding(unbonding: &Unbonding): Object<Metadata> {
@@ -2763,8 +2430,6 @@ Get metadata
from
-
-
## Function `get_validator_from_unbonding`
@@ -2777,8 +2442,7 @@ Get validator
from
-Implementation
+##### Implementation
public fun get_validator_from_unbonding(unbonding: &Unbonding): String {
@@ -2788,8 +2452,6 @@ Get validator
from
-
## Function `get_release_time_from_unbonding`
@@ -2802,8 +2464,7 @@ Get release_time
from get_release_time_from_unbonding(unbonding: &Unbonding): u64 {
@@ -2813,8 +2474,6 @@ Get release_time
from
## Function `get_unbonding_share_from_unbonding`
@@ -2822,24 +2481,21 @@ Get release_time
from Unbonding
-