diff --git a/CHANGELOG.md b/CHANGELOG.md index 4fe77ed0..0de9f403 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,11 +10,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ### Added - [#285](https://github.com/FuelLabs/sway-libs/pull/285) Adds the `BytecodeRoot` and `ContractConfigurables` types to the Bytecode Library. +- [#286](https://github.com/FuelLabs/sway-libs/pull/286) Adds the `_metadata()` function to the Asset Library. ### Changed -- Something changed here 1 -- Something changed here 2 +- [#286](https://github.com/FuelLabs/sway-libs/pull/286) Updates the repository to Sway-Standards v0.6.0 and implements the new SRC-20 and SRC-7 logging specifications. +- [#286](https://github.com/FuelLabs/sway-libs/pull/286) `_set_metadata()`, `_set_name()` and `_set_symbol()` now revert if the metadata is an empty string. +- [#286](https://github.com/FuelLabs/sway-libs/pull/286) `_set_metadata()` now reverts if the metadata is empty bytes. +- [#286](https://github.com/FuelLabs/sway-libs/pull/286) `_mint()` and `_burn()` now revert if the `amount` argument is zero. ### Fixed @@ -67,6 +70,79 @@ verify_predicate_address(my_predicate_address, my_bytecode, None); // No configu verify_predicate_address(my_predicate_address, my_bytecode, Some(my_configurables)); // With configurables ``` +- [#286](https://github.com/FuelLabs/sway-libs/pull/286) The support functions for `Metadata` have been removed. They have been moved to sway-standards. + +Before: + +```sway +use sway_libs::asset::metadata::*; + +fn foo(my_metadata: Metadata) { + let res: bool = my_metadata.is_b256(); + let res: bool = my_metadata.is_string(); + let res: bool = my_metadata.is_bytes(); + let res: bool = my_metadata.is_uint(); +} +``` + +After: + +```sway +use standards::src7::*; + +fn foo(my_metadata: Metadata) { + let res: bool = my_metadata.is_b256(); + let res: bool = my_metadata.is_string(); + let res: bool = my_metadata.is_bytes(); + let res: bool = my_metadata.is_uint(); +} +``` + +- [#286](https://github.com/FuelLabs/sway-libs/pull/286) The `SetMetadata` abi `set_metadata` function definition has changed. The `metadata` argument is now an `Option` and the argument order has changed. + +Before: + +```sway +abi SetAssetMetadata { + #[storage(read, write)] + fn set_metadata(asset: AssetId, key: String, metadata: Metadata); +} +``` + +After: + +```sway +abi SetAssetMetadata { + #[storage(read, write)] + fn set_metadata(asset: AssetId, metadata: Option, key: String); +} +``` + +- [#286](https://github.com/FuelLabs/sway-libs/pull/286) The `_set_name()`, `_set_symbol()`, `_mint()`, and `_set_metdata()` functions `name`, `symbol`, `sub_id`, and `metadata` arguments are now `Option`s. + +Before: + +```sway +fn foo(asset: AssetId, recipient: Identity, amount: u64, key: String, metadata: Metadata) { + _set_name(storage.name, asset, String::from_ascii_str("Ether")); + _set_symbol(storage.symbol, asset, String::from_ascii_str("ETH")); + _mint(storage.total_assets, storage.total_supply, recipient, SubId::zero(), amount); + _set_metadata(storage.metadata, asset, key, metadata); +} +``` + +After: + +```sway +fn foo(asset: AssetId, recipient: Identity, amount: u64, metadata: Metadata, key: String) { + _set_name(storage.name, asset, Some(String::from_ascii_str("Ether"))); + _set_symbol(storage.symbol, asset, Some(String::from_ascii_str("ETH"))); + _mint(storage.total_assets, storage.total_supply, recipient, Some(SubId::zero()), amount); + // Note: Ordering of arguments has changed for `_set_metadata()` + _set_metadata(storage.metadata, asset, Some(metadata), key); +} +``` + ## [v0.23.1] ### Added v0.23.1 diff --git a/docs/book/src/asset/base.md b/docs/book/src/asset/base.md index 227779ba..054e51f9 100644 --- a/docs/book/src/asset/base.md +++ b/docs/book/src/asset/base.md @@ -60,6 +60,8 @@ To use the Asset Library's base functionly, simply pass the `StorageKey` from th To set some the asset attributes for an Asset, use the `SetAssetAttributes` ABI provided by the Asset Library. The example below shows the implementation of the `SetAssetAttributes` ABI with no user defined restrictions or custom functionality. It is recommended that the [Ownership Library](../ownership/index.md) is used in conjunction with the `SetAssetAttributes` ABI to ensure only a single user has permissions to set an Asset's attributes. +The `_set_name()`, `_set_symbol()`, and `_set_decimals()` functions follows the SRC-20 standard for logging and will emit their respective log when called. + ```sway {{#include ../../../../examples/asset/setting_src20_attributes/src/main.sw:setting_src20_attributes}} ``` diff --git a/docs/book/src/asset/metadata.md b/docs/book/src/asset/metadata.md index ccd442ff..c066f68a 100644 --- a/docs/book/src/asset/metadata.md +++ b/docs/book/src/asset/metadata.md @@ -24,17 +24,6 @@ The Asset Library has the following complimentary data type for the [SRC-7](http - `StorageMetadata` -The following additional functionality for the [SRC-7](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/)'s `Metadata` type is provided: - -- `as_string()` -- `is_string()` -- `as_u64()` -- `is_u64()` -- `as_bytes()` -- `is_bytes()` -- `as_b256()` -- `is_b256()` - ## Setting Up Storage Once imported, the Asset Library's metadata functionality should be available. To use them, be sure to add the storage block bellow to your contract which enables the [SRC-7](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/) standard. @@ -47,7 +36,9 @@ Once imported, the Asset Library's metadata functionality should be available. T ### Setting Metadata -To set some metadata for an Asset, use the `SetAssetMetadata` ABI provided by the Asset Library. Be sure to follow the [SRC-9](https://docs.fuel.network/docs/sway-standards/src-9-metadata-keys/) standard for your `key`. It is recommended that the [Ownership Library](../ownership/index.md) is used in conjunction with the `SetAssetMetadata` ABI to ensure only a single user has permissions to set an Asset's metadata. +To set some metadata for an Asset, use the `SetAssetMetadata` ABI provided by the Asset Library with the `_set_metadata()` function. Be sure to follow the [SRC-9](https://docs.fuel.network/docs/sway-standards/src-9-metadata-keys/) standard for your `key`. It is recommended that the [Ownership Library](../ownership/index.md) is used in conjunction with the `SetAssetMetadata` ABI to ensure only a single user has permissions to set an Asset's metadata. + +The `_set_metadata()` function follows the SRC-7 standard for logging and will emit the `SetMetadataEvent` when called. ```sway {{#include ../../../../examples/asset/setting_src7_attributes/src/main.sw:setting_src7_attributes}} @@ -57,59 +48,8 @@ To set some metadata for an Asset, use the `SetAssetMetadata` ABI provided by th ### Implementing the SRC-7 Standard with StorageMetadata -To use the `StorageMetadata` type, simply get the stored metadata with the associated `key` and `AssetId`. The example below shows the implementation of the [SRC-7](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/) standard in combination with the Asset Library's `StorageMetadata` type with no user defined restrictions or custom functionality. - -```sway -{{#include ../../../../examples/asset/basic_src7/src/main.sw:basic_src7}} -``` - -## Using the `Metadata` Extensions - -The `Metadata` type defined by the [SRC-7](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/) standard can be one of 4 states: - -```sway -pub enum Metadata { - B256: b256, - Bytes: Bytes, - Int: u64, - String: String, -} -``` - -The Asset Library enables the following functionality for the `Metadata` type: - -### `is_b256()` and `as_b256()` - -The `is_b256()` check enables checking whether the `Metadata` type is a `b256`. -The `as_b256()` returns the `b256` of the `Metadata` type. - -```sway -{{#include ../../../../examples/asset/metadata_docs/src/main.sw:as_b256}} -``` - -### `is_bytes()` and `as_bytes()` - -The `is_bytes()` check enables checking whether the `Metadata` type is a `Bytes`. -The `as_bytes()` returns the `Bytes` of the `Metadata` type. - -```sway -{{#include ../../../../examples/asset/metadata_docs/src/main.sw:as_bytes}} -``` - -### `is_u64()` and `as_u64()` - -The `is_u64()` check enables checking whether the `Metadata` type is a `u64`. -The `as_u64()` returns the `u64` of the `Metadata` type. - -```sway -{{#include ../../../../examples/asset/metadata_docs/src/main.sw:as_u64}} -``` - -### `is_string()` and `as_string()` - -The `is_string()` check enables checking whether the `Metadata` type is a `String`. -The `as_string()` returns the `String` of the `Metadata` type. +To use the `StorageMetadata` type, simply get the stored metadata with the associated `key` and `AssetId` using the provided `_metadata()` convenience function. The example below shows the implementation of the [SRC-7](https://docs.fuel.network/docs/sway-standards/src-7-asset-metadata/) standard in combination with the Asset Library's `StorageMetadata` type and the `_metadata()` function with no user defined restrictions or custom functionality. ```sway -{{#include ../../../../examples/asset/metadata_docs/src/main.sw:as_string}} +{{#include ../../../../examples/asset/basic_src7/src/main.sw:src7_metadata_convenience_function}} ``` diff --git a/docs/book/src/asset/supply.md b/docs/book/src/asset/supply.md index 1d63c298..9057f994 100644 --- a/docs/book/src/asset/supply.md +++ b/docs/book/src/asset/supply.md @@ -37,7 +37,9 @@ Once imported, the Asset Library's supply functionality should be available. To ## Implementing the SRC-3 Standard with the Asset Library -To use a base function, simply pass the `StorageKey` from the prescribed storage block. The example below shows the implementation of the [SRC-3](https://docs.fuel.network/docs/sway-standards/src-3-minting-and-burning/) standard in combination with the Asset Library with no user defined restrictions or custom functionality. It is recommended that the [Ownership Library](../ownership/index.md) is used in conjunction with the Asset Library;s supply functionality to ensure only a single user has permissions to mint an Asset. +To use either function, simply pass the `StorageKey` from the prescribed storage block. The example below shows the implementation of the [SRC-3](https://docs.fuel.network/docs/sway-standards/src-3-minting-and-burning/) standard in combination with the Asset Library with no user defined restrictions or custom functionality. It is recommended that the [Ownership Library](../ownership/index.md) is used in conjunction with the Asset Library;s supply functionality to ensure only a single user has permissions to mint an Asset. + +The `_mint()` and `_burn()` functions follows the SRC-20 standard for logging and will emit the `TotalSupplyEvent` when called. ```sway {{#include ../../../../examples/asset/basic_src3/src/main.sw:basic_src3}} diff --git a/examples/Forc.lock b/examples/Forc.lock index b9587a52..d8fe4859 100644 --- a/examples/Forc.lock +++ b/examples/Forc.lock @@ -141,7 +141,7 @@ dependencies = [ [[package]] name = "standards" -source = "git+https://github.com/FuelLabs/sway-standards?tag=v0.5.2#270350e69bd7455b7e99f0aae2e29a94d42324bd" +source = "git+https://github.com/FuelLabs/sway-standards?tag=v0.6.0#65e09f95ea8b9476b171a66c8a47108f352fa32c" dependencies = ["std"] [[package]] diff --git a/examples/admin/Forc.toml b/examples/admin/Forc.toml index c01483cf..7cc2ca3c 100644 --- a/examples/admin/Forc.toml +++ b/examples/admin/Forc.toml @@ -5,5 +5,5 @@ license = "Apache-2.0" name = "admin_examples" [dependencies] -standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.5.2" } +standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.6.0" } sway_libs = { path = "../../libs" } diff --git a/examples/asset/base_docs/Forc.toml b/examples/asset/base_docs/Forc.toml index 6dc4619a..2d6a05b3 100644 --- a/examples/asset/base_docs/Forc.toml +++ b/examples/asset/base_docs/Forc.toml @@ -5,5 +5,5 @@ license = "Apache-2.0" name = "base_docs" [dependencies] -standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.5.2" } +standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.6.0" } sway_libs = { path = "../../../libs" } diff --git a/examples/asset/basic_src20/Forc.toml b/examples/asset/basic_src20/Forc.toml index b7659901..d7aac164 100644 --- a/examples/asset/basic_src20/Forc.toml +++ b/examples/asset/basic_src20/Forc.toml @@ -5,5 +5,5 @@ license = "Apache-2.0" name = "basic_src20" [dependencies] -standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.5.2" } +standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.6.0" } sway_libs = { path = "../../../libs" } diff --git a/examples/asset/basic_src3/Forc.toml b/examples/asset/basic_src3/Forc.toml index b4871c59..f40716f6 100644 --- a/examples/asset/basic_src3/Forc.toml +++ b/examples/asset/basic_src3/Forc.toml @@ -5,5 +5,5 @@ license = "Apache-2.0" name = "basic_src3" [dependencies] -standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.5.2" } +standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.6.0" } sway_libs = { path = "../../../libs" } diff --git a/examples/asset/basic_src3/src/main.sw b/examples/asset/basic_src3/src/main.sw index 2835b13c..3851570b 100644 --- a/examples/asset/basic_src3/src/main.sw +++ b/examples/asset/basic_src3/src/main.sw @@ -14,7 +14,7 @@ storage { // Implement the SRC-3 Standard for this contract impl SRC3 for Contract { #[storage(read, write)] - fn mint(recipient: Identity, sub_id: SubId, amount: u64) { + fn mint(recipient: Identity, sub_id: Option, amount: u64) { // Pass the StorageKeys to the `_mint()` function from the Asset Library. _mint( storage diff --git a/examples/asset/basic_src7/Forc.toml b/examples/asset/basic_src7/Forc.toml index d6d7244a..ed59196f 100644 --- a/examples/asset/basic_src7/Forc.toml +++ b/examples/asset/basic_src7/Forc.toml @@ -5,5 +5,5 @@ license = "Apache-2.0" name = "basic_src7" [dependencies] -standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.5.2" } +standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.6.0" } sway_libs = { path = "../../../libs" } diff --git a/examples/asset/metadata_docs/Forc.toml b/examples/asset/metadata_docs/Forc.toml index f429e97a..ef132d46 100644 --- a/examples/asset/metadata_docs/Forc.toml +++ b/examples/asset/metadata_docs/Forc.toml @@ -5,5 +5,5 @@ license = "Apache-2.0" name = "metadata_docs" [dependencies] -standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.5.2" } +standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.6.0" } sway_libs = { path = "../../../libs" } diff --git a/examples/asset/metadata_docs/src/main.sw b/examples/asset/metadata_docs/src/main.sw index 57eb7cc3..0150f09a 100644 --- a/examples/asset/metadata_docs/src/main.sw +++ b/examples/asset/metadata_docs/src/main.sw @@ -3,7 +3,7 @@ contract; use std::{bytes::Bytes, string::String}; // ANCHOR: import -use sway_libs::asset::metadata::*; +use sway_libs::asset::metadata::{_metadata, _set_metadata, SetAssetMetadata, StorageMetadata}; use standards::src7::*; // ANCHOR_END: import @@ -20,34 +20,20 @@ storage { } // ANCHOR_END: src7_storage -// ANCHOR: as_b256 -fn b256_type(my_metadata: Metadata) { - assert(my_metadata.is_b256()); - - let my_b256: b256 = my_metadata.as_b256().unwrap(); -} -// ANCHOR_END: as_b256 - -// ANCHOR: as_bytes -fn bytes_type(my_metadata: Metadata) { - assert(my_metadata.is_bytes()); - - let my_bytes: Bytes = my_metadata.as_bytes().unwrap(); -} -// ANCHOR_END: as_bytes - -// ANCHOR: as_u64 -fn u64_type(my_metadata: Metadata) { - assert(my_metadata.is_u64()); - - let my_u64: u64 = my_metadata.as_u64().unwrap(); +// ANCHOR src7_metadata_convenience_function +impl SRC7 for Contract { + #[storage(read)] + fn metadata(asset: AssetId, key: String) -> Option { + _metadata(storage.metadata, asset, key) + } } -// ANCHOR_END: as_u64 - -// ANCHOR: as_string -fn string_type(my_metadata: Metadata) { - assert(my_metadata.is_string()); - - let my_string: String = my_metadata.as_string().unwrap(); +// ANCHOR src7_metadata_convenience_function + +// ANCHOR: src7_set_metadata +impl SetAssetMetadata for Contract { + #[storage(read, write)] + fn set_metadata(asset: AssetId, metadata: Option, key: String) { + _set_metadata(storage.metadata, asset, metadata, key); + } } -// ANCHOR_END: as_string +// ANCHOR_END: src7_set_metadata diff --git a/examples/asset/setting_src20_attributes/Forc.toml b/examples/asset/setting_src20_attributes/Forc.toml index 109673c5..cebfd6e3 100644 --- a/examples/asset/setting_src20_attributes/Forc.toml +++ b/examples/asset/setting_src20_attributes/Forc.toml @@ -5,5 +5,5 @@ license = "Apache-2.0" name = "setting_src20_attributes" [dependencies] -standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.5.2" } +standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.6.0" } sway_libs = { path = "../../../libs" } diff --git a/examples/asset/setting_src20_attributes/src/main.sw b/examples/asset/setting_src20_attributes/src/main.sw index 0ac8df9a..0023e984 100644 --- a/examples/asset/setting_src20_attributes/src/main.sw +++ b/examples/asset/setting_src20_attributes/src/main.sw @@ -12,12 +12,12 @@ storage { impl SetAssetAttributes for Contract { #[storage(write)] - fn set_name(asset: AssetId, name: String) { + fn set_name(asset: AssetId, name: Option) { _set_name(storage.name, asset, name); } #[storage(write)] - fn set_symbol(asset: AssetId, symbol: String) { + fn set_symbol(asset: AssetId, symbol: Option) { _set_symbol(storage.symbol, asset, symbol); } diff --git a/examples/asset/setting_src7_attributes/Forc.toml b/examples/asset/setting_src7_attributes/Forc.toml index f1dc4f94..57cacdfc 100644 --- a/examples/asset/setting_src7_attributes/Forc.toml +++ b/examples/asset/setting_src7_attributes/Forc.toml @@ -5,5 +5,5 @@ license = "Apache-2.0" name = "setting_src7_attributes" [dependencies] -standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.5.2" } +standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.6.0" } sway_libs = { path = "../../../libs" } diff --git a/examples/asset/setting_src7_attributes/src/main.sw b/examples/asset/setting_src7_attributes/src/main.sw index be17835f..1c20f771 100644 --- a/examples/asset/setting_src7_attributes/src/main.sw +++ b/examples/asset/setting_src7_attributes/src/main.sw @@ -12,8 +12,8 @@ storage { impl SetAssetMetadata for Contract { #[storage(read, write)] - fn set_metadata(asset: AssetId, key: String, metadata: Metadata) { - _set_metadata(storage.metadata, asset, key, metadata); + fn set_metadata(asset: AssetId, metadata: Option, key: String) { + _set_metadata(storage.metadata, asset, metadata, key); } } // ANCHOR_END: setting_src7_attributes diff --git a/examples/asset/supply_docs/Forc.toml b/examples/asset/supply_docs/Forc.toml index 2722843b..102751a2 100644 --- a/examples/asset/supply_docs/Forc.toml +++ b/examples/asset/supply_docs/Forc.toml @@ -5,5 +5,5 @@ license = "Apache-2.0" name = "supply_docs" [dependencies] -standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.5.2" } +standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.6.0" } sway_libs = { path = "../../../libs" } diff --git a/examples/asset/supply_docs/src/main.sw b/examples/asset/supply_docs/src/main.sw index 2575e5bc..30ede1dd 100644 --- a/examples/asset/supply_docs/src/main.sw +++ b/examples/asset/supply_docs/src/main.sw @@ -10,7 +10,7 @@ use standards::src3::*; // ANCHOR: src3_abi abi SRC3 { #[storage(read, write)] - fn mint(recipient: Identity, vault_sub_id: SubId, amount: u64); + fn mint(recipient: Identity, sub_id: Option, amount: u64); #[payable] #[storage(read, write)] fn burn(vault_sub_id: SubId, amount: u64); diff --git a/examples/ownership/Forc.toml b/examples/ownership/Forc.toml index 72adea04..93c78a21 100644 --- a/examples/ownership/Forc.toml +++ b/examples/ownership/Forc.toml @@ -5,5 +5,5 @@ license = "Apache-2.0" name = "ownership_examples" [dependencies] -standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.5.2" } +standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.6.0" } sway_libs = { path = "../../libs" } diff --git a/examples/upgradability/Forc.toml b/examples/upgradability/Forc.toml index c4364b2c..df6aa50d 100644 --- a/examples/upgradability/Forc.toml +++ b/examples/upgradability/Forc.toml @@ -5,5 +5,5 @@ license = "Apache-2.0" name = "upgradability_examples" [dependencies] -standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.5.2" } +standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.6.0" } sway_libs = { path = "../../libs" } diff --git a/libs/Forc.lock b/libs/Forc.lock index a516af41..8710191c 100644 --- a/libs/Forc.lock +++ b/libs/Forc.lock @@ -4,7 +4,7 @@ source = "path+from-root-E19CE48B3E858B72" [[package]] name = "standards" -source = "git+https://github.com/FuelLabs/sway-standards?tag=v0.5.2#270350e69bd7455b7e99f0aae2e29a94d42324bd" +source = "git+https://github.com/FuelLabs/sway-standards?tag=v0.6.0#65e09f95ea8b9476b171a66c8a47108f352fa32c" dependencies = ["std"] [[package]] diff --git a/libs/Forc.toml b/libs/Forc.toml index 4db34db5..abc5f2ec 100644 --- a/libs/Forc.toml +++ b/libs/Forc.toml @@ -5,4 +5,4 @@ license = "Apache-2.0" name = "sway_libs" [dependencies] -standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.5.2" } +standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.6.0" } diff --git a/libs/src/asset/base.sw b/libs/src/asset/base.sw index b4f73cfa..656ca1c9 100644 --- a/libs/src/asset/base.sw +++ b/libs/src/asset/base.sw @@ -1,6 +1,8 @@ library; use std::{hash::{Hash, sha256}, storage::storage_string::*, string::String}; +use standards::src20::{SetDecimalsEvent, SetNameEvent, SetSymbolEvent}; +use ::asset::errors::SetMetadataError; /// Returns the total number of individual assets for a contract. /// @@ -199,7 +201,11 @@ pub fn _decimals( /// /// * `name_key`: [StorageKey>>] - The location in storage which the `StorageMap` that stores the names of assets is stored. /// * `asset`: [AssetId] - The asset of which to set the name. -/// * `name`: [String] - The name of the asset. +/// * `name`: [Option] - The name of the asset. +/// +/// # Reverts +/// +/// * When passing an empty string. /// /// # Number of Storage Accesses /// @@ -217,18 +223,33 @@ pub fn _decimals( /// /// fn foo(asset: AssetId) { /// let name = String::from_ascii_str("Ether"); -/// _set_name(storage.name, asset, name); -/// assert(_name(storage.name, asset) == name); +/// _set_name(storage.name, asset, Some(name)); +/// assert(_name(storage.name, asset).unwrap() == name); /// } /// ``` #[storage(write)] pub fn _set_name( name_key: StorageKey>, asset: AssetId, - name: String, + name: Option, ) { - name_key.insert(asset, StorageString {}); - name_key.get(asset).write_slice(name); + match name { + Some(name) => { + require(!name.is_empty(), SetMetadataError::EmptyString); + + name_key.insert(asset, StorageString {}); + name_key.get(asset).write_slice(name); + }, + None => { + let _ = name_key.get(asset).clear(); + } + } + + log(SetNameEvent { + asset, + name, + sender: msg_sender().unwrap(), + }); } /// Unconditionally sets the symbol of an asset. @@ -241,7 +262,11 @@ pub fn _set_name( /// /// * `symbol_key`: [StorageKey>>] - The location in storage which the `StorageMap` that stores the symbols of assets is stored. /// * `asset`: [AssetId] - The asset of which to set the symbol. -/// * `symbol`: [String] - The symbol of the asset. +/// * `symbol`: [Option] - The symbol of the asset. +/// +/// # Reverts +/// +/// * When passing an empty string. /// /// # Number of Storage Accesses /// @@ -259,18 +284,33 @@ pub fn _set_name( /// /// fn foo(asset: AssetId) { /// let symbol = String::from_ascii_str("ETH"); -/// _set_symbol(storage.symbol, asset, symbol); -/// assert(_symbol(storage.symbol, asset) == symbol); +/// _set_symbol(storage.symbol, asset, Some(symbol)); +/// assert(_symbol(storage.symbol, asset).unwrap() == symbol); /// } /// ``` #[storage(write)] pub fn _set_symbol( symbol_key: StorageKey>, asset: AssetId, - symbol: String, + symbol: Option, ) { - symbol_key.insert(asset, StorageString {}); - symbol_key.get(asset).write_slice(symbol); + match symbol { + Some(symbol) => { + require(!symbol.is_empty(), SetMetadataError::EmptyString); + + symbol_key.insert(asset, StorageString {}); + symbol_key.get(asset).write_slice(symbol); + }, + None => { + let _ = symbol_key.get(asset).clear(); + } + } + + log(SetSymbolEvent { + asset, + symbol: symbol, + sender: msg_sender().unwrap(), + }); } /// Unconditionally sets the decimals of an asset. @@ -293,7 +333,6 @@ pub fn _set_symbol( /// /// ```sway /// use sway_libs::asset::base::{_set_decimals, _decimals}; -/// use std::string::String; /// /// storage { /// decimals: StorageMap = StorageMap {}, @@ -302,7 +341,7 @@ pub fn _set_symbol( /// fn foo(asset: AssetId) { /// let decimals = 8u8; /// _set_decimals(storage.decimals, asset, decimals); -/// assert(_decimals(storage.decimals, asset) == decimals); +/// assert(_decimals(storage.decimals, asset).unwrap() == decimals); /// } /// ``` #[storage(write)] @@ -312,13 +351,78 @@ pub fn _set_decimals( decimals: u8, ) { decimals_key.insert(asset, decimals); + + log(SetDecimalsEvent { + asset, + decimals, + sender: msg_sender().unwrap(), + }); } abi SetAssetAttributes { + /// Stores the name for a specific asset. + /// + /// # Arguments + /// + /// * `asset`: [AssetId] - The asset for the name to be stored. + /// * `name`: [Option] - The name which to be stored. + /// + /// # Example + /// + /// ```sway + /// use standards::src20::SRC20; + /// use sway_libs::asset::base::*; + /// use std::string::String; + /// + /// fn foo(contract_id: ContractId, asset: AssetId, name: Option) { + /// let contract_abi = abi(SetAssetAttributes, contract_id.bits()); + /// contract_abi.set_name(asset, name); + /// assert(contract_abi.name(asset) == name); + /// } + /// ``` #[storage(write)] - fn set_name(asset: AssetId, name: String); + fn set_name(asset: AssetId, name: Option); + /// Stores the symbol for a specific asset. + /// + /// # Arguments + /// + /// * `asset`: [AssetId] - The asset for the symbol to be stored. + /// * `symbol`: [Option] - The symbol which to be stored. + /// + /// # Example + /// + /// ```sway + /// use standards::src20::SRC20; + /// use sway_libs::asset::base::*; + /// use std::string::String; + /// + /// fn foo(contract_id: ContractId, asset: AssetId, symbol: Option) { + /// let contract_abi = abi(SetAssetAttributes, contract_id.bits()); + /// contract_abi.set_symbol(asset, symbol); + /// assert(contract_abi.symbol(asset) == symbol); + /// } + /// ``` #[storage(write)] - fn set_symbol(asset: AssetId, symbol: String); + fn set_symbol(asset: AssetId, symbol: Option); + /// Stores the decimals for a specific asset. + /// + /// # Arguments + /// + /// * `asset`: [AssetId] - The asset for the symbol to be stored. + /// * `decimals`: [u8] - The decimals which to be stored. + /// + /// # Example + /// + /// ```sway + /// use standards::src20::SRC20; + /// use sway_libs::asset::base::*; + /// + /// fn foo(contract_id: ContractId, asset: AssetId, decimals: u8) { + /// let contract_abi = abi(SetAssetAttributes, contract_id.bits()); + /// contract_abi.set_decimals(asset, decimals); + /// assert(contract_abi.decimals(asset).unwrap() == decimals); + /// } + /// ``` #[storage(write)] fn set_decimals(asset: AssetId, decimals: u8); } diff --git a/libs/src/asset/errors.sw b/libs/src/asset/errors.sw index 0f74207e..53dc36ea 100644 --- a/libs/src/asset/errors.sw +++ b/libs/src/asset/errors.sw @@ -4,4 +4,20 @@ library; pub enum BurnError { /// Emitted when there are not enough coins owned by the contract to burn. NotEnoughCoins: (), + /// Emitted when attempting to burn zero coins. + ZeroAmount: (), +} + +/// Error log for when something goes wrong when minting assets. +pub enum MintError { + /// Emitted when attempting to mint zero coins. + ZeroAmount: (), +} + +/// Error log for when something goes wrong when setting metadata. +pub enum SetMetadataError { + /// Emitted when the metadata is an empty string. + EmptyString: (), + /// Emitted when the metadata is empty bytes. + EmptyBytes: (), } diff --git a/libs/src/asset/metadata.sw b/libs/src/asset/metadata.sw index 4af81c82..fac9a69b 100644 --- a/libs/src/asset/metadata.sw +++ b/libs/src/asset/metadata.sw @@ -1,6 +1,6 @@ library; -use standards::src7::Metadata; +use standards::src7::{Metadata, SetMetadataEvent}; use std::{ auth::msg_sender, bytes::Bytes, @@ -18,18 +18,7 @@ use std::{ }, string::String, }; - -/// The event emitted when metadata is set via the `_set_metadata()` function. -pub struct SetMetadataEvent { - /// The asset for which metadata is set. - asset: AssetId, - /// The `Identity` of the caller that set the metadata. - sender: Identity, - /// The Metadata that is set. - metadata: Metadata, - /// The key used for the metadata. - key: String, -} +use ::asset::errors::SetMetadataError; /// A persistent storage type to store the SRC-7; Metadata Standard type. /// @@ -47,6 +36,11 @@ impl StorageKey { /// * `key`: [String] - The key for the metadata to be stored. /// * `metadata`: [Metadata] - The metadata which to be stored. /// + /// # Reverts + /// + /// * When the metadata is an empty string. + /// * When the metadata is an empty bytes. + /// /// # Number of Storage Accesses /// /// * Writes: `2` @@ -56,6 +50,7 @@ impl StorageKey { /// ```sway /// use standards::src7::Metadata; /// use sway_libs::asset::metadata::*; + /// use std::string::String; /// /// storage { /// metadata: StorageMetadata = StorageMetadata {} @@ -66,29 +61,48 @@ impl StorageKey { /// } /// ``` #[storage(read, write)] - pub fn insert(self, asset: AssetId, key: String, metadata: Metadata) { + pub fn insert( + self, + asset: AssetId, + metadata: Option, + key: String, +) { let hashed_key = sha256((asset, key)); match metadata { - Metadata::Int(data) => { + Some(Metadata::Int(data)) => { write(hashed_key, 0, data); - write(sha256((hashed_key, self.slot())), 0, 0); + write(sha256((hashed_key, self.slot())), 0, 1); }, - Metadata::B256(data) => { + Some(Metadata::B256(data)) => { write(hashed_key, 0, data); - write(sha256((hashed_key, self.slot())), 0, 1); + write(sha256((hashed_key, self.slot())), 0, 2); }, - Metadata::String(data) => { + Some(Metadata::String(data)) => { + require(!data.is_empty(), SetMetadataError::EmptyString); + let storage_string: StorageKey = StorageKey::new(hashed_key, 0, hashed_key); storage_string.write_slice(data); - write(sha256((hashed_key, self.slot())), 0, 2); + write(sha256((hashed_key, self.slot())), 0, 3); }, - Metadata::Bytes(data) => { + Some(Metadata::Bytes(data)) => { + require(!data.is_empty(), SetMetadataError::EmptyBytes); + let storage_bytes: StorageKey = StorageKey::new(hashed_key, 0, hashed_key); storage_bytes.write_slice(data); - write(sha256((hashed_key, self.slot())), 0, 3); + write(sha256((hashed_key, self.slot())), 0, 4); + }, + None => { + write(sha256((hashed_key, self.slot())), 0, 0); } } + + log(SetMetadataEvent { + asset, + metadata: metadata, + key, + sender: msg_sender().unwrap(), + }); } /// Returns metadata for a specific asset and key pair. @@ -111,6 +125,7 @@ impl StorageKey { /// ```sway /// use standards::src7::Metadata; /// use sway_libs::asset::metadata::*; + /// use std::string::String; /// /// storage { /// metadata: StorageMetadata = StorageMetadata {} @@ -126,21 +141,21 @@ impl StorageKey { let hashed_key = sha256((asset, key)); match read::(sha256((hashed_key, self.slot())), 0) { - Option::Some(0) => { - Option::Some(Metadata::Int(read::(hashed_key, 0).unwrap())) + Some(1) => { + Some(Metadata::Int(read::(hashed_key, 0).unwrap())) }, - Option::Some(1) => { - Option::Some(Metadata::B256(read::(hashed_key, 0).unwrap())) + Some(2) => { + Some(Metadata::B256(read::(hashed_key, 0).unwrap())) }, - Option::Some(2) => { + Some(3) => { let storage_string: StorageKey = StorageKey::new(hashed_key, 0, hashed_key); - Option::Some(Metadata::String(storage_string.read_slice().unwrap())) + Some(Metadata::String(storage_string.read_slice().unwrap_or(String::new()))) }, - Option::Some(3) => { + Some(4) => { let storage_bytes: StorageKey = StorageKey::new(hashed_key, 0, hashed_key); - Option::Some(Metadata::Bytes(storage_bytes.read_slice().unwrap())) + Some(Metadata::Bytes(storage_bytes.read_slice().unwrap_or(Bytes::new()))) }, - _ => Option::None, + _ => None, } } } @@ -151,8 +166,8 @@ impl StorageKey { /// /// * `metadata_key`: [StorageKey] - The storage location for metadata. /// * `asset`: [AssetId] - The asset for the metadata to be stored. +/// * `metadata`: [Option] - The metadata which to be stored. /// * `key`: [String] - The key for the metadata to be stored. -/// * `metadata`: [Metadata] - The metadata which to be stored. /// /// # Number of Storage Accesses /// @@ -163,254 +178,84 @@ impl StorageKey { /// ```sway /// use standards::src7::Metadata; /// use sway_libs::asset::metadata::*; +/// use std::string::String; /// /// storage { /// metadata: StorageMetadata = StorageMetadata {} /// } /// -/// fn foo(asset: AssetId, key: String, metadata: Metadata) { -/// _set_metadata(storage.metadata, asset, key, metadata); +/// fn foo(asset: AssetId, key: String, metadata: Option) { +/// _set_metadata(storage.metadata, asset, metadata, key); /// } /// ``` #[storage(read, write)] pub fn _set_metadata( metadata_key: StorageKey, asset: AssetId, + metadata: Option, key: String, - metadata: Metadata, ) { - log(SetMetadataEvent { - asset, - sender: msg_sender().unwrap(), - metadata, - key, - }); - metadata_key.insert(asset, key, metadata); + metadata_key.insert(asset, metadata, key); } -abi SetAssetMetadata { - #[storage(read, write)] - fn set_metadata(asset: AssetId, key: String, metadata: Metadata); +/// Returns metadata for a specific asset and key pair. +/// +/// # Arguments +/// +/// * `metadata_key`: [StorageKey] - The storage location for metadata. +/// * `asset`: [AssetId] - The asset for the metadata to be read. +/// * `metadata`: [Option] - The metadata which to be read. +/// * `key`: [String] - The key for the metadata to be read. +/// +/// # Number of Storage Accesses +/// +/// * Reads: `2` +/// +/// # Example +/// +/// ```sway +/// use standards::src7::Metadata; +/// use sway_libs::asset::metadata::*; +/// use std::string::String; +/// +/// storage { +/// metadata: StorageMetadata = StorageMetadata {} +/// } +/// +/// fn foo(asset: AssetId, key: String) { +/// let result: Option = _metadata(storage.metadata, asset, key); +/// } +/// ``` +#[storage(read)] +pub fn _metadata( + metadata_key: StorageKey, + asset: AssetId, + key: String, +) -> Option { + metadata_key.get(asset, key) } - -impl Metadata { - /// Returns the underlying metadata as a `String`. - /// - /// # Returns - /// - /// * [Option] - `Some` if the underlying type is a `String`, otherwise `None`. - /// - /// # Examples - /// - /// ```sway - /// use std::string::String; - /// use sway_libs::asset::metadata::*; - /// use standards::src7::{SRC7, Metadata}; - /// - /// fn foo(contract_id: ContractId, asset: AssetId, key: String) { - /// let metadata_abi = abi(SRC7, contract_id); - /// let metadata = metadata_abi.metadata(asset, key); - /// - /// let string = metadata.unwrap().as_string(); - /// assert(string.len() != 0); - /// } - /// ``` - pub fn as_string(self) -> Option { - match self { - Self::String(data) => Option::Some(data), - _ => Option::None, - } - } - - /// Returns whether the underlying metadata is a `String`. - /// - /// # Returns - /// - /// * [bool] - `true` if the metadata is a `String`, otherwise `false`. - /// - /// # Examples - /// - /// ```sway - /// use std::string::String; - /// use sway_libs::asset::metadata::*; - /// use standards::src7::{SRC7, Metadata}; - /// - /// fn foo(contract_id: ContractId, asset: AssetId, key: String) { - /// let metadata_abi = abi(SRC7, contract_id); - /// let metadata = metadata_abi.metadata(asset, key); - /// - /// assert(metadata.unwrap().is_string()); - /// } - /// ``` - pub fn is_string(self) -> bool { - match self { - Self::String(_) => true, - _ => false, - } - } - - /// Returns the underlying metadata as a `u64`. - /// - /// # Returns - /// - /// * [Option] - `Some` if the underlying type is a `u64`, otherwise `None`. - /// - /// # Examples - /// - /// ```sway - /// use std::string::String; - /// use sway_libs::asset::metadata::*; - /// use standards::src7::{SRC7, Metadata}; - /// - /// fn foo(contract_id: ContractId, asset: AssetId, key: String) { - /// let metadata_abi = abi(SRC7, contract_id); - /// let metadata = metadata_abi.metadata(asset, key); - /// - /// let int = metadata.unwrap().as_u64(); - /// assert(int != 0); - /// } - /// ``` - pub fn as_u64(self) -> Option { - match self { - Self::Int(data) => Option::Some(data), - _ => Option::None, - } - } - - /// Returns whether the underlying metadata is a `u64`. - /// - /// # Returns - /// - /// * [bool] - `true` if the metadata is a `u64`, otherwise `false`. - /// - /// # Examples - /// - /// ```sway - /// use std::string::String; - /// use sway_libs::asset::metadata::*; - /// use standards::src7::{SRC7, Metadata}; - /// - /// fn foo(contract_id: ContractId, asset: AssetId, key: String) { - /// let metadata_abi = abi(SRC7, contract_id); - /// let metadata = metadata_abi.metadata(asset, key); - /// - /// assert(metadata.unwrap().is_u64()); - /// } - /// ``` - pub fn is_u64(self) -> bool { - match self { - Self::Int(_) => true, - _ => false, - } - } - - /// Returns the underlying metadata as `Bytes`. - /// - /// # Returns - /// - /// * [Option] - `Some` if the underlying type is `Bytes`, otherwise `None`. - /// - /// # Examples - /// - /// ```sway - /// use std::{bytes::Bytes, string::String}; - /// use sway_libs::asset::metadata::*; - /// use standards::src7::{SRC7, Metadata}; - /// - /// fn foo(contract_id: ContractId, asset: AssetId, key: String) { - /// let metadata_abi = abi(SRC7, contract_id); - /// let metadata = metadata_abi.metadata(asset, key); - /// - /// let bytes = metadata.unwrap().as_bytes(); - /// assert(bytes.len() != 0); - /// } - /// ``` - pub fn as_bytes(self) -> Option { - match self { - Self::Bytes(data) => Option::Some(data), - _ => Option::None, - } - } - - /// Returns whether the underlying metadata is `Bytes`. +abi SetAssetMetadata { + /// Stores metadata for a specific asset and key pair. /// - /// # Returns + /// # Arguments /// - /// * [bool] - `true` if the metadata is `Bytes`, otherwise `false`. + /// * `asset`: [AssetId] - The asset for the metadata to be stored. + /// * `metadata`: [Option] - The metadata which to be stored. + /// * `key`: [String] - The key for the metadata to be stored. /// - /// # Examples + /// # Example /// /// ```sway - /// use std::{bytes::Bytes, string::String}; - /// use sway_libs::asset::metadata::*; /// use standards::src7::{SRC7, Metadata}; - /// - /// fn foo(contract_id: ContractId, asset: AssetId, key: String) { - /// let metadata_abi = abi(SRC7, contract_id); - /// let metadata = metadata_abi.metadata(asset, key); - /// - /// assert(metadata.unwrap().is_bytes()); - /// } - /// ``` - pub fn is_bytes(self) -> bool { - match self { - Self::Bytes(_) => true, - _ => false, - } - } - - /// Returns the underlying metadata as a `b256`. - /// - /// # Returns - /// - /// * [Option] - `Some` if the underlying type is a `b256`, otherwise `None`. - /// - /// # Examples - /// - /// ```sway - /// use std::string::String; /// use sway_libs::asset::metadata::*; - /// use standards::src7::{SRC7, Metadata}; - /// - /// fn foo(contract_id: ContractId, asset: AssetId, key: String) { - /// let metadata_abi = abi(SRC7, contract_id); - /// let metadata = metadata_abi.metadata(asset, key); - /// - /// let val = metadata.unwrap().as_b256(); - /// assert(val != b256::zero()); - /// } - /// ``` - pub fn as_b256(self) -> Option { - match self { - Self::B256(data) => Option::Some(data), - _ => Option::None, - } - } - - /// Returns whether the underlying metadata is a `b256`. - /// - /// # Returns - /// - /// * [bool] - `true` if the metadata is a `b256`, otherwise `false`. - /// - /// # Examples - /// - /// ```sway /// use std::string::String; - /// use sway_libs::asset::metadata::*; - /// use standards::src7::{SRC7, Metadata}; - /// - /// fn foo(contract_id: ContractId, asset: AssetId, key: String) { - /// let metadata_abi = abi(SRC7, contract_id); - /// let metadata = metadata_abi.metadata(asset, key); /// - /// assert(metadata.unwrap().is_b256()); + /// fn foo(contract_id: ContractId, asset: AssetId, metadata: Option, key: String) { + /// let contract_abi = abi(SetAssetMetadata, contract_id.bits()); + /// contract_abi.set_metadata(asset, metadata, key); + /// assert(contract_abi.metadata(asset, key).unwrap() == Metadata); /// } /// ``` - pub fn is_b256(self) -> bool { - match self { - Self::B256(_) => true, - _ => false, - } - } + #[storage(read, write)] + fn set_metadata(asset: AssetId, metadata: Option, key: String); } diff --git a/libs/src/asset/supply.sw b/libs/src/asset/supply.sw index bce20fcd..4e2e5490 100644 --- a/libs/src/asset/supply.sw +++ b/libs/src/asset/supply.sw @@ -1,6 +1,6 @@ library; -use ::asset::errors::BurnError; +use ::asset::errors::{BurnError, MintError}; use ::asset::base::{_total_assets, _total_supply}; use std::{ asset::{ @@ -16,25 +16,31 @@ use std::{ storage::storage_string::*, string::String, }; +use standards::src20::TotalSupplyEvent; /// Unconditionally mints new assets using the `sub_id` sub-identifier. /// /// # Additional Information /// /// **Warning** This function increases the total supply by the number of coins minted. +/// **Note:** If `None` is passed for the `sub_id` argument, `b256::zero()` is used as the `SubId`. /// /// # Arguments /// /// * `total_assets_key`: [StorageKey] - The location in storage that the `u64` which represents the total assets is stored. /// * `total_supply_key`: [StorageKey>] - The location in storage which the `StorageMap` that stores the total supply of assets is stored. /// * `recipient`: [Identity] - The user to which the newly minted asset is transferred to. -/// * `sub_id`: [SubId] - The sub-identifier of the newly minted asset. +/// * `sub_id`: [Option] - The sub-identifier of the newly minted asset. /// * `amount`: [u64] - The quantity of coins to mint. /// /// # Returns /// /// * [AssetId] - The `AssetId` of the newly minted asset. /// +/// # Reverts +/// +/// * When `amount` is zero. +/// /// # Number of Storage Accesses /// /// * Reads: `2` @@ -62,9 +68,14 @@ pub fn _mint( total_assets_key: StorageKey, total_supply_key: StorageKey>, recipient: Identity, - sub_id: SubId, + sub_id: Option, amount: u64, ) -> AssetId { + require(amount > 0, MintError::ZeroAmount); + let sub_id = match sub_id { + Some(id) => id, + None => b256::zero(), + }; let asset_id = AssetId::new(ContractId::this(), sub_id); let supply = _total_supply(total_supply_key, asset_id); @@ -77,6 +88,12 @@ pub fn _mint( total_supply_key.insert(asset_id, current_supply + amount); mint_to(recipient, sub_id, amount); + log(TotalSupplyEvent { + asset: asset_id, + supply: current_supply + amount, + sender: msg_sender().unwrap(), + }); + asset_id } @@ -96,6 +113,7 @@ pub fn _mint( /// # Reverts /// /// * When the calling contract does not have enough assets. +/// * When `amount` is zero. /// /// # Number of Storage Accesses /// @@ -124,6 +142,7 @@ pub fn _burn( sub_id: SubId, amount: u64, ) { + require(amount > 0, BurnError::ZeroAmount); let asset_id = AssetId::new(ContractId::this(), sub_id); require(this_balance(asset_id) >= amount, BurnError::NotEnoughCoins); @@ -133,4 +152,9 @@ pub fn _burn( total_supply_key.insert(asset_id, supply - amount); burn(sub_id, amount); + log(TotalSupplyEvent { + asset: asset_id, + supply: supply - amount, + sender: msg_sender().unwrap(), + }); } diff --git a/tests/Forc.lock b/tests/Forc.lock index 3f4107b2..88243c18 100644 --- a/tests/Forc.lock +++ b/tests/Forc.lock @@ -210,7 +210,7 @@ dependencies = ["std"] [[package]] name = "standards" -source = "git+https://github.com/FuelLabs/sway-standards?tag=v0.5.2#270350e69bd7455b7e99f0aae2e29a94d42324bd" +source = "git+https://github.com/FuelLabs/sway-standards?tag=v0.6.0#65e09f95ea8b9476b171a66c8a47108f352fa32c" dependencies = ["std"] [[package]] diff --git a/tests/src/admin/Forc.toml b/tests/src/admin/Forc.toml index 82663096..5319dd7a 100644 --- a/tests/src/admin/Forc.toml +++ b/tests/src/admin/Forc.toml @@ -5,5 +5,5 @@ license = "Apache-2.0" name = "admin_test" [dependencies] -standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.5.2" } +standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.6.0" } sway_libs = { path = "../../../libs" } diff --git a/tests/src/native_asset/Forc.toml b/tests/src/native_asset/Forc.toml index feaebf2b..1040f253 100644 --- a/tests/src/native_asset/Forc.toml +++ b/tests/src/native_asset/Forc.toml @@ -5,5 +5,5 @@ license = "Apache-2.0" name = "native_asset_lib" [dependencies] -standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.5.2" } +standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.6.0" } sway_libs = { path = "../../../libs" } diff --git a/tests/src/native_asset/src/main.sw b/tests/src/native_asset/src/main.sw index bc019e00..1ee749e4 100644 --- a/tests/src/native_asset/src/main.sw +++ b/tests/src/native_asset/src/main.sw @@ -59,8 +59,8 @@ impl SRC20 for Contract { impl SRC3 for Contract { #[storage(read, write)] - fn mint(recipient: Identity, sub_id: SubId, amount: u64) { - _mint( + fn mint(recipient: Identity, sub_id: Option, amount: u64) { + let _ = _mint( storage .total_assets, storage @@ -81,18 +81,18 @@ impl SRC3 for Contract { impl SRC7 for Contract { #[storage(read)] fn metadata(asset: AssetId, key: String) -> Option { - storage.metadata.get(asset, key) + _metadata(storage.metadata, asset, key) } } impl SetAssetAttributes for Contract { #[storage(write)] - fn set_name(asset: AssetId, name: String) { + fn set_name(asset: AssetId, name: Option) { _set_name(storage.name, asset, name); } #[storage(write)] - fn set_symbol(asset: AssetId, symbol: String) { + fn set_symbol(asset: AssetId, symbol: Option) { _set_symbol(storage.symbol, asset, symbol); } @@ -104,8 +104,8 @@ impl SetAssetAttributes for Contract { impl SetAssetMetadata for Contract { #[storage(read, write)] - fn set_metadata(asset: AssetId, key: String, metadata: Metadata) { - _set_metadata(storage.metadata, asset, key, metadata); + fn set_metadata(asset: AssetId, metadata: Option, key: String) { + _set_metadata(storage.metadata, asset, metadata, key); } } @@ -120,10 +120,10 @@ fn test_total_assets() { assert(src20_abi.total_assets() == 0); - src3_abi.mint(recipient, sub_id1, 10); + src3_abi.mint(recipient, Some(sub_id1), 10); assert(src20_abi.total_assets() == 1); - src3_abi.mint(recipient, sub_id2, 10); + src3_abi.mint(recipient, Some(sub_id2), 10); assert(src20_abi.total_assets() == 2); } @@ -138,10 +138,10 @@ fn test_total_supply() { assert(src20_abi.total_supply(asset_id).is_none()); - src3_abi.mint(recipient, sub_id, 10); + src3_abi.mint(recipient, Some(sub_id), 10); assert(src20_abi.total_supply(asset_id).unwrap() == 10); - src3_abi.mint(recipient, sub_id, 10); + src3_abi.mint(recipient, Some(sub_id), 10); assert(src20_abi.total_supply(asset_id).unwrap() == 20); } @@ -157,7 +157,7 @@ fn test_name() { assert(src20_abi.name(asset_id).is_none()); - attributes_abi.set_name(asset_id, name); + attributes_abi.set_name(asset_id, Some(name)); assert(src20_abi.name(asset_id).unwrap().as_bytes() == name.as_bytes()); } @@ -173,7 +173,7 @@ fn test_symbol() { assert(src20_abi.symbol(asset_id).is_none()); - attributes_abi.set_symbol(asset_id, symbol); + attributes_abi.set_symbol(asset_id, Some(symbol)); assert(src20_abi.symbol(asset_id).unwrap().as_bytes() == symbol.as_bytes()); } @@ -206,7 +206,7 @@ fn test_mint() { assert(balance_of(ContractId::from(CONTRACT_ID), asset_id) == 0); - src3_abi.mint(recipient, sub_id, 10); + src3_abi.mint(recipient, Some(sub_id), 10); assert(balance_of(ContractId::from(CONTRACT_ID), asset_id) == 10); } @@ -221,77 +221,13 @@ fn test_burn() { let sub_id = SubId::zero(); let asset_id = AssetId::new(ContractId::from(CONTRACT_ID), sub_id); - src3_abi.mint(recipient, sub_id, 10); + src3_abi.mint(recipient, Some(sub_id), 10); assert(balance_of(ContractId::from(CONTRACT_ID), asset_id) == 10); src3_abi.burn(sub_id, 10); assert(balance_of(ContractId::from(CONTRACT_ID), asset_id) == 0); } -#[test] -fn test_metadata_as_string() { - let data_string = String::from_ascii_str("Fuel is blazingly fast"); - let metadata = Metadata::String(data_string); - - assert(data_string == metadata.as_string().unwrap()); -} - -#[test] -fn test_metadata_is_string() { - let data_string = String::from_ascii_str("Fuel is blazingly fast"); - let metadata = Metadata::String(data_string); - - assert(metadata.is_string()); -} - -#[test] -fn test_metadata_as_u64() { - let data_int = 1; - let metadata = Metadata::Int(data_int); - - assert(data_int == metadata.as_u64().unwrap()); -} - -#[test] -fn test_metadata_is_u64() { - let data_int = 1; - let metadata = Metadata::Int(data_int); - - assert(metadata.is_u64()); -} - -#[test] -fn test_metadata_as_bytes() { - let data_bytes = String::from_ascii_str("Fuel is blazingly fast").as_bytes(); - let metadata = Metadata::Bytes(data_bytes); - - assert(data_bytes == metadata.as_bytes().unwrap()); -} - -#[test] -fn test_metadata_is_bytes() { - let data_bytes = String::from_ascii_str("Fuel is blazingly fast").as_bytes(); - let metadata = Metadata::Bytes(data_bytes); - - assert(metadata.is_bytes()); -} - -#[test] -fn test_metadata_as_b256() { - let data_b256 = 0x0000000000000000000000000000000000000000000000000000000000000001; - let metadata = Metadata::B256(data_b256); - - assert(data_b256 == metadata.as_b256().unwrap()); -} - -#[test] -fn test_metadata_is_b256() { - let data_b256 = 0x0000000000000000000000000000000000000000000000000000000000000001; - let metadata = Metadata::B256(data_b256); - - assert(metadata.is_b256()); -} - #[test] fn test_set_metadata_b256() { let data_b256 = 0x0000000000000000000000000000000000000000000000000000000000000001; @@ -301,7 +237,7 @@ fn test_set_metadata_b256() { let set_metadata_abi = abi(SetAssetMetadata, CONTRACT_ID); let key = String::from_ascii_str("my_key"); - set_metadata_abi.set_metadata(asset_id, key, metadata); + set_metadata_abi.set_metadata(asset_id, Some(metadata), key); let returned_metadata = src7_abi.metadata(asset_id, key); assert(returned_metadata.is_some()); @@ -317,7 +253,7 @@ fn test_set_metadata_u64() { let set_metadata_abi = abi(SetAssetMetadata, CONTRACT_ID); let key = String::from_ascii_str("my_key"); - set_metadata_abi.set_metadata(asset_id, key, metadata); + set_metadata_abi.set_metadata(asset_id, Some(metadata), key); let returned_metadata = src7_abi.metadata(asset_id, key); assert(returned_metadata.is_some()); @@ -333,7 +269,7 @@ fn test_set_metadata_string() { let set_metadata_abi = abi(SetAssetMetadata, CONTRACT_ID); let key = String::from_ascii_str("my_key"); - set_metadata_abi.set_metadata(asset_id, key, metadata); + set_metadata_abi.set_metadata(asset_id, Some(metadata), key); let returned_metadata = src7_abi.metadata(asset_id, key); assert(returned_metadata.is_some()); @@ -349,7 +285,7 @@ fn test_set_metadata_bytes() { let set_metadata_abi = abi(SetAssetMetadata, CONTRACT_ID); let key = String::from_ascii_str("my_key"); - set_metadata_abi.set_metadata(asset_id, key, metadata); + set_metadata_abi.set_metadata(asset_id, Some(metadata), key); let returned_metadata = src7_abi.metadata(asset_id, key); assert(returned_metadata.is_some()); @@ -369,7 +305,7 @@ fn total_assets_only_incremented_once() { assert(src20_abi.total_assets() == 0); - src3_abi.mint(recipient, sub_id, 10); + src3_abi.mint(recipient, Some(sub_id), 10); assert(balance_of(ContractId::from(CONTRACT_ID), asset_id) == 10); assert(src20_abi.total_assets() == 1); @@ -379,7 +315,7 @@ fn total_assets_only_incremented_once() { assert(src20_abi.total_assets() == 1); - src3_abi.mint(recipient, sub_id, 10); + src3_abi.mint(recipient, Some(sub_id), 10); assert(balance_of(ContractId::from(CONTRACT_ID), asset_id) == 10); assert(src20_abi.total_assets() == 1); diff --git a/tests/src/native_asset/tests/functions/burn.rs b/tests/src/native_asset/tests/functions/burn.rs index 85b9fa39..a6107259 100644 --- a/tests/src/native_asset/tests/functions/burn.rs +++ b/tests/src/native_asset/tests/functions/burn.rs @@ -1,7 +1,8 @@ use crate::native_asset::tests::utils::{ interface::{burn, mint, total_assets, total_supply}, - setup::{defaults, get_wallet_balance, setup}, + setup::{defaults, get_wallet_balance, setup, TotalSupplyEvent}, }; +use fuels::types::Identity; mod success { @@ -11,82 +12,287 @@ mod success { async fn burn_assets() { let (owner_wallet, other_wallet, id, instance_1, instance_2) = setup().await; let (asset_id_1, _asset_id_2, sub_id_1, _sub_id_2, _owner_identity, identity2) = - defaults(id, owner_wallet, other_wallet.clone()); + defaults(id, owner_wallet.clone(), other_wallet.clone()); + let mint_amount_1 = 100; + let burn_amount_1 = 25; + + assert!(mint_amount_1 >= burn_amount_1); + + mint(&instance_1, identity2, Some(sub_id_1), mint_amount_1).await; + + assert_eq!( + get_wallet_balance(&other_wallet, &asset_id_1).await, + mint_amount_1 + ); + assert_eq!( + total_supply(&instance_1, asset_id_1).await, + Some(mint_amount_1) + ); + assert_eq!(total_assets(&instance_1).await, 1); - mint(&instance_1, identity2, sub_id_1, 100).await; + let response = burn(&instance_2, asset_id_1, sub_id_1, burn_amount_1).await; - assert_eq!(get_wallet_balance(&other_wallet, &asset_id_1).await, 100); - assert_eq!(total_supply(&instance_1, asset_id_1).await, Some(100)); + assert_eq!( + get_wallet_balance(&other_wallet, &asset_id_1).await, + mint_amount_1 - burn_amount_1 + ); + assert_eq!( + total_supply(&instance_1, asset_id_1).await, + Some(mint_amount_1 - burn_amount_1) + ); assert_eq!(total_assets(&instance_1).await, 1); + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + assert_eq!( + *event, + TotalSupplyEvent { + asset: asset_id_1, + supply: mint_amount_1 - burn_amount_1, + sender: Identity::Address(other_wallet.address().into()), + } + ); + } - burn(&instance_2, asset_id_1, sub_id_1, 50).await; + #[tokio::test] + async fn burn_twice() { + let (owner_wallet, other_wallet, id, instance_1, instance_2) = setup().await; + let (asset_id_1, _asset_id_2, sub_id_1, _sub_id_2, _owner_identity, identity2) = + defaults(id, owner_wallet.clone(), other_wallet.clone()); + let mint_amount_1 = 100; + let burn_amount_1 = 25; + let burn_amount_2 = 30; + let burn_amount_3 = 3; + + assert!(mint_amount_1 >= burn_amount_1 + burn_amount_2 + burn_amount_3); + + mint(&instance_1, identity2, Some(sub_id_1), mint_amount_1).await; + + assert_eq!( + get_wallet_balance(&other_wallet, &asset_id_1).await, + mint_amount_1 + ); + assert_eq!( + total_supply(&instance_1, asset_id_1).await, + Some(mint_amount_1) + ); + assert_eq!(total_assets(&instance_1).await, 1); - assert_eq!(get_wallet_balance(&other_wallet, &asset_id_1).await, 50); - assert_eq!(total_supply(&instance_1, asset_id_1).await, Some(50)); + let response = burn(&instance_2, asset_id_1, sub_id_1, burn_amount_1).await; + assert_eq!( + get_wallet_balance(&other_wallet, &asset_id_1).await, + mint_amount_1 - burn_amount_1 + ); + assert_eq!( + total_supply(&instance_1, asset_id_1).await, + Some(mint_amount_1 - burn_amount_1) + ); assert_eq!(total_assets(&instance_1).await, 1); + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + assert_eq!( + *event, + TotalSupplyEvent { + asset: asset_id_1, + supply: mint_amount_1 - burn_amount_1, + sender: Identity::Address(other_wallet.address().into()), + } + ); + + let response = burn(&instance_2, asset_id_1, sub_id_1, burn_amount_2).await; + assert_eq!( + get_wallet_balance(&other_wallet, &asset_id_1).await, + mint_amount_1 - burn_amount_1 - burn_amount_2 + ); + assert_eq!( + total_supply(&instance_1, asset_id_1).await, + Some(mint_amount_1 - burn_amount_1 - burn_amount_2) + ); + assert_eq!(total_assets(&instance_1).await, 1); + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + assert_eq!( + *event, + TotalSupplyEvent { + asset: asset_id_1, + supply: mint_amount_1 - burn_amount_1 - burn_amount_2, + sender: Identity::Address(other_wallet.address().into()), + } + ); + + let response = burn(&instance_2, asset_id_1, sub_id_1, burn_amount_3).await; + assert_eq!( + get_wallet_balance(&other_wallet, &asset_id_1).await, + mint_amount_1 - burn_amount_1 - burn_amount_2 - burn_amount_3 + ); + assert_eq!( + total_supply(&instance_1, asset_id_1).await, + Some(mint_amount_1 - burn_amount_1 - burn_amount_2 - burn_amount_3) + ); + assert_eq!(total_assets(&instance_1).await, 1); + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + assert_eq!( + *event, + TotalSupplyEvent { + asset: asset_id_1, + supply: mint_amount_1 - burn_amount_1 - burn_amount_2 - burn_amount_3, + sender: Identity::Address(other_wallet.address().into()), + } + ); } #[tokio::test] async fn burns_multiple_assets() { let (owner_wallet, other_wallet, id, instance_1, instance_2) = setup().await; let (asset_id_1, asset_id_2, sub_id_1, sub_id_2, _owner_identity, identity2) = - defaults(id, owner_wallet, other_wallet.clone()); - - mint(&instance_1, identity2.clone(), sub_id_1, 100).await; - mint(&instance_1, identity2, sub_id_2, 200).await; - - assert_eq!(get_wallet_balance(&other_wallet, &asset_id_1).await, 100); - assert_eq!(get_wallet_balance(&other_wallet, &asset_id_2).await, 200); - assert_eq!(total_supply(&instance_1, asset_id_1).await, Some(100)); - assert_eq!(total_supply(&instance_1, asset_id_2).await, Some(200)); + defaults(id, owner_wallet.clone(), other_wallet.clone()); + let mint_amount_1 = 100; + let mint_amount_2 = 200; + let burn_amount_1 = 25; + let burn_amount_2 = 150; + + assert!(mint_amount_1 >= burn_amount_1); + assert!(mint_amount_2 >= burn_amount_2); + + mint( + &instance_1, + identity2.clone(), + Some(sub_id_1), + mint_amount_1, + ) + .await; + mint(&instance_1, identity2, Some(sub_id_2), mint_amount_2).await; + + assert_eq!( + get_wallet_balance(&other_wallet, &asset_id_1).await, + mint_amount_1 + ); + assert_eq!( + get_wallet_balance(&other_wallet, &asset_id_2).await, + mint_amount_2 + ); + assert_eq!( + total_supply(&instance_1, asset_id_1).await, + Some(mint_amount_1) + ); + assert_eq!( + total_supply(&instance_1, asset_id_2).await, + Some(mint_amount_2) + ); assert_eq!(total_assets(&instance_1).await, 2); - burn(&instance_2, asset_id_1, sub_id_1, 50).await; - - assert_eq!(get_wallet_balance(&other_wallet, &asset_id_1).await, 50); - assert_eq!(get_wallet_balance(&other_wallet, &asset_id_2).await, 200); - assert_eq!(total_supply(&instance_1, asset_id_1).await, Some(50)); - assert_eq!(total_supply(&instance_1, asset_id_2).await, Some(200)); + let response = burn(&instance_2, asset_id_1, sub_id_1, burn_amount_1).await; + + assert_eq!( + get_wallet_balance(&other_wallet, &asset_id_1).await, + mint_amount_1 - burn_amount_1 + ); + assert_eq!( + get_wallet_balance(&other_wallet, &asset_id_2).await, + mint_amount_2 + ); + assert_eq!( + total_supply(&instance_1, asset_id_1).await, + Some(mint_amount_1 - burn_amount_1) + ); + assert_eq!( + total_supply(&instance_1, asset_id_2).await, + Some(mint_amount_2) + ); assert_eq!(total_assets(&instance_1).await, 2); - - burn(&instance_2, asset_id_2, sub_id_2, 100).await; - - assert_eq!(get_wallet_balance(&other_wallet, &asset_id_1).await, 50); - assert_eq!(get_wallet_balance(&other_wallet, &asset_id_2).await, 100); - assert_eq!(total_supply(&instance_1, asset_id_1).await, Some(50)); - assert_eq!(total_supply(&instance_1, asset_id_2).await, Some(100)); + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + assert_eq!( + *event, + TotalSupplyEvent { + asset: asset_id_1, + supply: mint_amount_1 - burn_amount_1, + sender: Identity::Address(other_wallet.address().into()), + } + ); + + let response = burn(&instance_2, asset_id_2, sub_id_2, burn_amount_2).await; + + assert_eq!( + get_wallet_balance(&other_wallet, &asset_id_1).await, + mint_amount_1 - burn_amount_1 + ); + assert_eq!( + get_wallet_balance(&other_wallet, &asset_id_2).await, + mint_amount_2 - burn_amount_2 + ); + assert_eq!( + total_supply(&instance_1, asset_id_1).await, + Some(mint_amount_1 - burn_amount_1) + ); + assert_eq!( + total_supply(&instance_1, asset_id_2).await, + Some(mint_amount_2 - burn_amount_2) + ); assert_eq!(total_assets(&instance_1).await, 2); + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + assert_eq!( + *event, + TotalSupplyEvent { + asset: asset_id_2, + supply: mint_amount_2 - burn_amount_2, + sender: Identity::Address(other_wallet.address().into()), + } + ); } #[tokio::test] async fn burn_to_zero() { let (owner_wallet, other_wallet, id, instance_1, instance_2) = setup().await; let (asset_id_1, _asset_id_2, sub_id_1, _sub_id_2, _owner_identity, identity2) = - defaults(id, owner_wallet, other_wallet.clone()); - - mint(&instance_1, identity2, sub_id_1, 100).await; - - assert_eq!(get_wallet_balance(&other_wallet, &asset_id_1).await, 100); - assert_eq!(total_supply(&instance_1, asset_id_1).await, Some(100)); - assert_eq!(total_assets(&instance_1).await, 1); - - burn(&instance_2, asset_id_1, sub_id_1, 50).await; - - assert_eq!(get_wallet_balance(&other_wallet, &asset_id_1).await, 50); - assert_eq!(total_supply(&instance_1, asset_id_1).await, Some(50)); - assert_eq!(total_assets(&instance_1).await, 1); - - burn(&instance_2, asset_id_1, sub_id_1, 25).await; - - assert_eq!(get_wallet_balance(&other_wallet, &asset_id_1).await, 25); - assert_eq!(total_supply(&instance_1, asset_id_1).await, Some(25)); + defaults(id, owner_wallet.clone(), other_wallet.clone()); + let mint_amount_1 = 100; + let burn_amount_1 = 100; + + assert!(mint_amount_1 == burn_amount_1); + + mint(&instance_1, identity2, Some(sub_id_1), mint_amount_1).await; + + assert_eq!( + get_wallet_balance(&other_wallet, &asset_id_1).await, + mint_amount_1 + ); + assert_eq!( + total_supply(&instance_1, asset_id_1).await, + Some(mint_amount_1) + ); assert_eq!(total_assets(&instance_1).await, 1); - burn(&instance_2, asset_id_1, sub_id_1, 25).await; + let response = burn(&instance_2, asset_id_1, sub_id_1, burn_amount_1).await; assert_eq!(get_wallet_balance(&other_wallet, &asset_id_1).await, 0); assert_eq!(total_supply(&instance_1, asset_id_1).await, Some(0)); assert_eq!(total_assets(&instance_1).await, 1); + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + assert_eq!( + *event, + TotalSupplyEvent { + asset: asset_id_1, + supply: 0, + sender: Identity::Address(other_wallet.address().into()), + } + ); } } @@ -100,17 +306,48 @@ mod revert { #[tokio::test] #[should_panic(expected = "NotEnoughCoins")] - async fn when_not_enough_coins() { + async fn when_not_enough_coins_in_transaction() { + let (owner_wallet, other_wallet, id, instance_1, instance_2) = setup().await; + let (asset_id_1, _asset_id_2, sub_id_1, _sub_id_2, _identity1, identity2) = + defaults(id, owner_wallet, other_wallet.clone()); + let mint_amount = 100; + let sent_burn_amount = 50; + let claimed_burn_amount = 75; + + assert!(sent_burn_amount < claimed_burn_amount); + + mint(&instance_1, identity2, Some(sub_id_1), mint_amount).await; + + let call_params = CallParameters::new(sent_burn_amount, asset_id_1, 1_000_000); + instance_2 + .methods() + .burn(sub_id_1, claimed_burn_amount) + .with_tx_policies(TxPolicies::default().with_script_gas_limit(2_000_000)) + .call_params(call_params) + .unwrap() + .call() + .await + .unwrap(); + } + + #[tokio::test] + #[should_panic(expected = "NotEnoughCoins")] + async fn when_greater_than_supply() { let (owner_wallet, other_wallet, id, instance_1, instance_2) = setup().await; let (asset_id_1, _asset_id_2, sub_id_1, _sub_id_2, _identity1, identity2) = defaults(id, owner_wallet, other_wallet.clone()); + let mint_amount = 100; + let sent_burn_amount = 100; + let claimed_burn_amount = 150; - mint(&instance_1, identity2, sub_id_1, 100).await; + assert!(mint_amount < claimed_burn_amount); - let call_params = CallParameters::new(50, asset_id_1, 1_000_000); + mint(&instance_1, identity2, Some(sub_id_1), mint_amount).await; + + let call_params = CallParameters::new(sent_burn_amount, asset_id_1, 1_000_000); instance_2 .methods() - .burn(sub_id_1, 150) + .burn(sub_id_1, claimed_burn_amount) .with_tx_policies(TxPolicies::default().with_script_gas_limit(2_000_000)) .call_params(call_params) .unwrap() @@ -125,13 +362,18 @@ mod revert { let (owner_wallet, other_wallet, id, instance_1, instance_2) = setup().await; let (asset_id_1, _asset_id_2, sub_id_1, sub_id_2, _identity1, identity2) = defaults(id, owner_wallet, other_wallet.clone()); + let mint_amount = 100; + let sent_burn_amount = 50; + let claimed_burn_amount = 50; + + assert!(sent_burn_amount == claimed_burn_amount); - mint(&instance_1, identity2, sub_id_1, 100).await; + mint(&instance_1, identity2, Some(sub_id_1), mint_amount).await; - let call_params = CallParameters::new(50, asset_id_1, 1_000_000); + let call_params = CallParameters::new(sent_burn_amount, asset_id_1, 1_000_000); instance_2 .methods() - .burn(sub_id_2, 50) + .burn(sub_id_2, claimed_burn_amount) .with_tx_policies(TxPolicies::default().with_script_gas_limit(2_000_000)) .call_params(call_params) .unwrap() @@ -146,13 +388,18 @@ mod revert { let (owner_wallet, other_wallet, id, instance_1, instance_2) = setup().await; let (_asset_id_1, _asset_id_2, sub_id_1, _sub_id_2, _identity1, identity2) = defaults(id, owner_wallet, other_wallet.clone()); + let mint_amount = 100; + let sent_burn_amount = 50; + let claimed_burn_amount = 50; - mint(&instance_1, identity2, sub_id_1, 100).await; + assert!(sent_burn_amount == claimed_burn_amount); - let call_params = CallParameters::new(50, AssetId::zeroed(), 1_000_000); + mint(&instance_1, identity2, Some(sub_id_1), mint_amount).await; + + let call_params = CallParameters::new(sent_burn_amount, AssetId::zeroed(), 1_000_000); instance_2 .methods() - .burn(sub_id_1, 50) + .burn(sub_id_1, claimed_burn_amount) .with_tx_policies(TxPolicies::default().with_script_gas_limit(2_000_000)) .call_params(call_params) .unwrap() @@ -160,4 +407,20 @@ mod revert { .await .unwrap(); } + + #[tokio::test] + #[should_panic(expected = "ZeroAmount")] + async fn when_burn_zero() { + let (owner_wallet, other_wallet, id, instance_1, instance_2) = setup().await; + let (asset_id_1, _asset_id_2, sub_id_1, _sub_id_2, _owner_identity, identity2) = + defaults(id, owner_wallet.clone(), other_wallet.clone()); + let mint_amount_1 = 100; + let burn_amount_1 = 0; + + assert!(burn_amount_1 == 0); + + mint(&instance_1, identity2, Some(sub_id_1), mint_amount_1).await; + + burn(&instance_2, asset_id_1, sub_id_1, burn_amount_1).await; + } } diff --git a/tests/src/native_asset/tests/functions/decimals.rs b/tests/src/native_asset/tests/functions/decimals.rs index d1377f00..397258be 100644 --- a/tests/src/native_asset/tests/functions/decimals.rs +++ b/tests/src/native_asset/tests/functions/decimals.rs @@ -13,11 +13,12 @@ mod success { let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; let (asset_id_1, _asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = defaults(id, owner_wallet, other_wallet.clone()); + let decimals_1 = 9u8; assert_eq!(decimals(&instance_1, asset_id_1).await, None); - set_decimals(&instance_1, asset_id_1, 9u8).await; - assert_eq!(decimals(&instance_1, asset_id_1).await, Some(9u8)); + set_decimals(&instance_1, asset_id_1, decimals_1).await; + assert_eq!(decimals(&instance_1, asset_id_1).await, Some(decimals_1)); } #[tokio::test] @@ -25,28 +26,31 @@ mod success { let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; let (asset_id_1, asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = defaults(id, owner_wallet, other_wallet.clone()); + let decimals_1 = 9u8; + let decimals_2 = u8::MIN; + let decimals_3 = u8::MAX; + let decimals_4 = 16u8; + let decimals_5 = 9u8; + let asset_id_3 = get_asset_id(Bytes32::from([3u8; 32]), id); + let asset_id_4 = get_asset_id(Bytes32::from([4u8; 32]), id); + let asset_id_5 = get_asset_id(Bytes32::from([5u8; 32]), id); assert_eq!(decimals(&instance_1, asset_id_1).await, None); - set_decimals(&instance_1, asset_id_1, 9u8).await; - assert_eq!(decimals(&instance_1, asset_id_1).await, Some(9u8)); - assert_eq!(decimals(&instance_1, asset_id_2).await, None); - set_decimals(&instance_1, asset_id_2, 8u8).await; - assert_eq!(decimals(&instance_1, asset_id_2).await, Some(8u8)); - - let asset_id_3 = get_asset_id(Bytes32::from([3u8; 32]), id); assert_eq!(decimals(&instance_1, asset_id_3).await, None); - set_decimals(&instance_1, asset_id_3, 7u8).await; - assert_eq!(decimals(&instance_1, asset_id_3).await, Some(7u8)); - - let asset_id_4 = get_asset_id(Bytes32::from([4u8; 32]), id); assert_eq!(decimals(&instance_1, asset_id_4).await, None); - set_decimals(&instance_1, asset_id_4, 6u8).await; - assert_eq!(decimals(&instance_1, asset_id_4).await, Some(6u8)); - - let asset_id_5 = get_asset_id(Bytes32::from([5u8; 32]), id); assert_eq!(decimals(&instance_1, asset_id_5).await, None); - set_decimals(&instance_1, asset_id_5, 5u8).await; - assert_eq!(decimals(&instance_1, asset_id_5).await, Some(5u8)); + + set_decimals(&instance_1, asset_id_1, decimals_1).await; + set_decimals(&instance_1, asset_id_2, decimals_2).await; + set_decimals(&instance_1, asset_id_3, decimals_3).await; + set_decimals(&instance_1, asset_id_4, decimals_4).await; + set_decimals(&instance_1, asset_id_5, decimals_5).await; + + assert_eq!(decimals(&instance_1, asset_id_1).await, Some(decimals_1)); + assert_eq!(decimals(&instance_1, asset_id_2).await, Some(decimals_2)); + assert_eq!(decimals(&instance_1, asset_id_3).await, Some(decimals_3)); + assert_eq!(decimals(&instance_1, asset_id_4).await, Some(decimals_4)); + assert_eq!(decimals(&instance_1, asset_id_5).await, Some(decimals_5)); } } diff --git a/tests/src/native_asset/tests/functions/metadata.rs b/tests/src/native_asset/tests/functions/metadata.rs index 19a7c5a0..ca79648f 100644 --- a/tests/src/native_asset/tests/functions/metadata.rs +++ b/tests/src/native_asset/tests/functions/metadata.rs @@ -2,12 +2,22 @@ use crate::native_asset::tests::utils::{ interface::{metadata, set_metadata}, setup::{defaults, get_asset_id, setup, Metadata}, }; -use fuels::types::{Bytes, Bytes32}; +use fuels::types::{Bits256, Bytes, Bytes32}; mod success { use super::*; + #[tokio::test] + async fn gets_none_set() { + let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; + let (asset_id_1, _asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = + defaults(id, owner_wallet, other_wallet.clone()); + let key = String::from("key1"); + + assert_eq!(metadata(&instance_1, asset_id_1, key.clone()).await, None); + } + #[tokio::test] async fn gets_one_asset() { let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; @@ -18,7 +28,13 @@ mod success { assert_eq!(metadata(&instance_1, asset_id_1, key.clone()).await, None); - set_metadata(&instance_1, asset_id_1, key.clone(), metadata1.clone()).await; + set_metadata( + &instance_1, + asset_id_1, + key.clone(), + Some(metadata1.clone()), + ) + .await; assert_eq!( metadata(&instance_1, asset_id_1, key).await, Some(metadata1) @@ -33,25 +49,43 @@ mod success { let metadata1 = Metadata::String(String::from("Fuel NFT Metadata 1")); let metadata2 = Metadata::String(String::from("Fuel NFT Metadata 2")); let metadata3 = Metadata::String(String::from("Fuel NFT Metadata 3")); + let asset_id_3 = get_asset_id(Bytes32::from([3u8; 32]), id); let key = String::from("key1"); assert_eq!(metadata(&instance_1, asset_id_1, key.clone()).await, None); - set_metadata(&instance_1, asset_id_1, key.clone(), metadata1.clone()).await; + assert_eq!(metadata(&instance_1, asset_id_2, key.clone()).await, None); + assert_eq!(metadata(&instance_1, asset_id_3, key.clone()).await, None); + + set_metadata( + &instance_1, + asset_id_1, + key.clone(), + Some(metadata1.clone()), + ) + .await; + set_metadata( + &instance_1, + asset_id_2, + key.clone(), + Some(metadata2.clone()), + ) + .await; + set_metadata( + &instance_1, + asset_id_3, + key.clone(), + Some(metadata3.clone()), + ) + .await; + assert_eq!( metadata(&instance_1, asset_id_1, key.clone()).await, Some(metadata1) ); - - assert_eq!(metadata(&instance_1, asset_id_2, key.clone()).await, None); - set_metadata(&instance_1, asset_id_2, key.clone(), metadata2.clone()).await; assert_eq!( metadata(&instance_1, asset_id_2, key.clone()).await, Some(metadata2) ); - - let asset_id_3 = get_asset_id(Bytes32::from([3u8; 32]), id); - assert_eq!(metadata(&instance_1, asset_id_3, key.clone()).await, None); - set_metadata(&instance_1, asset_id_3, key.clone(), metadata3.clone()).await; assert_eq!( metadata(&instance_1, asset_id_3, key).await, Some(metadata3) @@ -69,41 +103,61 @@ mod success { Bytes::from_hex_str("0101010101010101010101010101010101010101010101010101010101010101") .expect("failed to convert to bytes"), ); + let metadata4 = Metadata::B256(Bits256([1u8; 32])); let key1 = String::from("key1"); let key2 = String::from("key2"); let key3 = String::from("key3"); + let key4 = String::from("key4"); assert_eq!(metadata(&instance_1, asset_id_1, key1.clone()).await, None); - set_metadata(&instance_1, asset_id_1, key1.clone(), metadata1.clone()).await; + assert_eq!(metadata(&instance_1, asset_id_1, key2.clone()).await, None); + assert_eq!(metadata(&instance_1, asset_id_1, key3.clone()).await, None); + assert_eq!(metadata(&instance_1, asset_id_1, key4.clone()).await, None); + + set_metadata( + &instance_1, + asset_id_1, + key1.clone(), + Some(metadata1.clone()), + ) + .await; + set_metadata( + &instance_1, + asset_id_1, + key2.clone(), + Some(metadata2.clone()), + ) + .await; + set_metadata( + &instance_1, + asset_id_1, + key3.clone(), + Some(metadata3.clone()), + ) + .await; + set_metadata( + &instance_1, + asset_id_1, + key4.clone(), + Some(metadata4.clone()), + ) + .await; + assert_eq!( metadata(&instance_1, asset_id_1, key1.clone()).await, - Some(metadata1.clone()) + Some(metadata1) ); - - assert_eq!(metadata(&instance_1, asset_id_1, key2.clone()).await, None); - set_metadata(&instance_1, asset_id_1, key2.clone(), metadata2.clone()).await; assert_eq!( metadata(&instance_1, asset_id_1, key2.clone()).await, - Some(metadata2.clone()) - ); - assert_eq!( - metadata(&instance_1, asset_id_1, key1.clone()).await, - Some(metadata1.clone()) + Some(metadata2) ); - - assert_eq!(metadata(&instance_1, asset_id_1, key3.clone()).await, None); - set_metadata(&instance_1, asset_id_1, key3.clone(), metadata3.clone()).await; assert_eq!( metadata(&instance_1, asset_id_1, key3).await, Some(metadata3) ); assert_eq!( - metadata(&instance_1, asset_id_1, key2.clone()).await, - Some(metadata2) - ); - assert_eq!( - metadata(&instance_1, asset_id_1, key1.clone()).await, - Some(metadata1) + metadata(&instance_1, asset_id_1, key4).await, + Some(metadata4) ); } } diff --git a/tests/src/native_asset/tests/functions/mint.rs b/tests/src/native_asset/tests/functions/mint.rs index a98b0fc2..2669c4aa 100644 --- a/tests/src/native_asset/tests/functions/mint.rs +++ b/tests/src/native_asset/tests/functions/mint.rs @@ -1,7 +1,8 @@ use crate::native_asset::tests::utils::{ interface::{mint, total_assets, total_supply}, - setup::{defaults, get_wallet_balance, setup}, + setup::{defaults, get_asset_id, get_wallet_balance, setup, TotalSupplyEvent}, }; +use fuels::types::{Bytes32, Identity}; mod success { @@ -11,39 +12,250 @@ mod success { async fn mints_assets() { let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; let (asset_id_1, _asset_id_2, sub_id_1, _sub_id_2, _identity1, identity2) = - defaults(id, owner_wallet, other_wallet.clone()); + defaults(id, owner_wallet.clone(), other_wallet.clone()); + let mint_amount = 100; assert_eq!(get_wallet_balance(&other_wallet, &asset_id_1).await, 0); assert_eq!(total_supply(&instance_1, asset_id_1).await, None); assert_eq!(total_assets(&instance_1).await, 0); - mint(&instance_1, identity2, sub_id_1, 100).await; + let response = mint(&instance_1, identity2, Some(sub_id_1), mint_amount).await; - assert_eq!(get_wallet_balance(&other_wallet, &asset_id_1).await, 100); - assert_eq!(total_supply(&instance_1, asset_id_1).await, Some(100)); + assert_eq!( + get_wallet_balance(&other_wallet, &asset_id_1).await, + mint_amount + ); + assert_eq!( + total_supply(&instance_1, asset_id_1).await, + Some(mint_amount) + ); assert_eq!(total_assets(&instance_1).await, 1); + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + assert_eq!( + *event, + TotalSupplyEvent { + asset: asset_id_1, + supply: mint_amount, + sender: Identity::Address(owner_wallet.address().into()), + } + ); + } + + #[tokio::test] + async fn mints_twice() { + let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; + let (asset_id_1, _asset_id_2, sub_id_1, _sub_id_2, _identity1, identity2) = + defaults(id, owner_wallet.clone(), other_wallet.clone()); + let mint_amount_1 = 100; + let mint_amount_2 = 200; + + let response = mint(&instance_1, identity2, Some(sub_id_1), mint_amount_1).await; + + assert_eq!( + get_wallet_balance(&other_wallet, &asset_id_1).await, + mint_amount_1 + ); + assert_eq!( + total_supply(&instance_1, asset_id_1).await, + Some(mint_amount_1) + ); + assert_eq!(total_assets(&instance_1).await, 1); + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + assert_eq!( + *event, + TotalSupplyEvent { + asset: asset_id_1, + supply: mint_amount_1, + sender: Identity::Address(owner_wallet.address().into()), + } + ); + + let response = mint(&instance_1, identity2, Some(sub_id_1), mint_amount_2).await; + assert_eq!( + get_wallet_balance(&other_wallet, &asset_id_1).await, + mint_amount_1 + mint_amount_2 + ); + assert_eq!( + total_supply(&instance_1, asset_id_1).await, + Some(mint_amount_1 + mint_amount_2) + ); + assert_eq!(total_assets(&instance_1).await, 1); + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + assert_eq!( + *event, + TotalSupplyEvent { + asset: asset_id_1, + supply: mint_amount_1 + mint_amount_2, + sender: Identity::Address(owner_wallet.address().into()), + } + ); + } + + #[tokio::test] + async fn mints_max() { + let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; + let (asset_id_1, _asset_id_2, sub_id_1, _sub_id_2, _identity1, identity2) = + defaults(id, owner_wallet.clone(), other_wallet.clone()); + let mint_amount = u64::MAX; + + assert_eq!(get_wallet_balance(&other_wallet, &asset_id_1).await, 0); + assert_eq!(total_supply(&instance_1, asset_id_1).await, None); + assert_eq!(total_assets(&instance_1).await, 0); + + let response = mint(&instance_1, identity2, Some(sub_id_1), mint_amount).await; + + assert_eq!( + get_wallet_balance(&other_wallet, &asset_id_1).await, + mint_amount + ); + assert_eq!( + total_supply(&instance_1, asset_id_1).await, + Some(mint_amount) + ); + assert_eq!(total_assets(&instance_1).await, 1); + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + assert_eq!( + *event, + TotalSupplyEvent { + asset: asset_id_1, + supply: mint_amount, + sender: Identity::Address(owner_wallet.address().into()), + } + ); + } + + #[tokio::test] + async fn mints_sub_id_none_assets() { + let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; + let (_asset_id_1, _asset_id_2, _sub_id_1, _sub_id_2, _identity1, identity2) = + defaults(id, owner_wallet.clone(), other_wallet.clone()); + let mint_amount = 100; + let asset_id = get_asset_id(Bytes32::zeroed(), id); + + assert_eq!(get_wallet_balance(&other_wallet, &asset_id).await, 0); + assert_eq!(total_supply(&instance_1, asset_id).await, None); + assert_eq!(total_assets(&instance_1).await, 0); + + let response = mint(&instance_1, identity2, None, mint_amount).await; + + assert_eq!( + get_wallet_balance(&other_wallet, &asset_id).await, + mint_amount + ); + assert_eq!(total_supply(&instance_1, asset_id).await, Some(mint_amount)); + assert_eq!(total_assets(&instance_1).await, 1); + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + assert_eq!( + *event, + TotalSupplyEvent { + asset: asset_id, + supply: mint_amount, + sender: Identity::Address(owner_wallet.address().into()), + } + ); } #[tokio::test] async fn mints_multiple_assets() { let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; let (asset_id_1, asset_id_2, sub_id_1, sub_id_2, _identity1, identity2) = - defaults(id, owner_wallet, other_wallet.clone()); + defaults(id, owner_wallet.clone(), other_wallet.clone()); + let mint_amount_1 = 100; + let mint_amount_2 = 200; - mint(&instance_1, identity2.clone(), sub_id_1, 100).await; + let response = mint( + &instance_1, + identity2.clone(), + Some(sub_id_1), + mint_amount_1, + ) + .await; - assert_eq!(get_wallet_balance(&other_wallet, &asset_id_1).await, 100); + assert_eq!( + get_wallet_balance(&other_wallet, &asset_id_1).await, + mint_amount_1 + ); assert_eq!(get_wallet_balance(&other_wallet, &asset_id_2).await, 0); - assert_eq!(total_supply(&instance_1, asset_id_1).await, Some(100)); + assert_eq!( + total_supply(&instance_1, asset_id_1).await, + Some(mint_amount_1) + ); assert_eq!(total_supply(&instance_1, asset_id_2).await, None); assert_eq!(total_assets(&instance_1).await, 1); + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + assert_eq!( + *event, + TotalSupplyEvent { + asset: asset_id_1, + supply: mint_amount_1, + sender: Identity::Address(owner_wallet.address().into()), + } + ); - mint(&instance_1, identity2, sub_id_2, 200).await; + let response = mint(&instance_1, identity2, Some(sub_id_2), mint_amount_2).await; - assert_eq!(get_wallet_balance(&other_wallet, &asset_id_1).await, 100); - assert_eq!(get_wallet_balance(&other_wallet, &asset_id_2).await, 200); - assert_eq!(total_supply(&instance_1, asset_id_1).await, Some(100)); - assert_eq!(total_supply(&instance_1, asset_id_2).await, Some(200)); + assert_eq!( + get_wallet_balance(&other_wallet, &asset_id_1).await, + mint_amount_1 + ); + assert_eq!( + get_wallet_balance(&other_wallet, &asset_id_2).await, + mint_amount_2 + ); + assert_eq!( + total_supply(&instance_1, asset_id_1).await, + Some(mint_amount_1) + ); + assert_eq!( + total_supply(&instance_1, asset_id_2).await, + Some(mint_amount_2) + ); assert_eq!(total_assets(&instance_1).await, 2); + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + assert_eq!( + *event, + TotalSupplyEvent { + asset: asset_id_2, + supply: mint_amount_2, + sender: Identity::Address(owner_wallet.address().into()), + } + ); + } +} + +mod revert { + + use super::*; + + #[tokio::test] + #[should_panic(expected = "ZeroAmount")] + async fn mints_zero() { + let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; + let (_asset_id_1, _asset_id_2, sub_id_1, _sub_id_2, _identity1, identity2) = + defaults(id, owner_wallet, other_wallet); + let mint_amount = 0; + + mint(&instance_1, identity2, Some(sub_id_1), mint_amount).await; } } diff --git a/tests/src/native_asset/tests/functions/name.rs b/tests/src/native_asset/tests/functions/name.rs index 75312b1b..d7bf607d 100644 --- a/tests/src/native_asset/tests/functions/name.rs +++ b/tests/src/native_asset/tests/functions/name.rs @@ -9,88 +9,57 @@ mod success { use super::*; #[tokio::test] - async fn one_asset() { + async fn get_none_asset_name() { let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; let (asset_id_1, _asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = - defaults(id, owner_wallet, other_wallet.clone()); + defaults(id, owner_wallet.clone(), other_wallet.clone()); assert_eq!(name(&instance_1, asset_id_1).await, None); - - set_name(&instance_1, asset_id_1, String::from("Fuel Asset 1")).await; - assert_eq!( - name(&instance_1, asset_id_1).await, - Some(String::from("Fuel Asset 1")) - ); } #[tokio::test] - async fn multiple_assets() { + async fn get_one_asset_name() { let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; - let (asset_id_1, asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = - defaults(id, owner_wallet, other_wallet.clone()); + let (asset_id_1, _asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = + defaults(id, owner_wallet.clone(), other_wallet.clone()); + let name_1 = String::from("Fuel Asset 1"); assert_eq!(name(&instance_1, asset_id_1).await, None); - set_name(&instance_1, asset_id_1, String::from("Fuel Asset 1")).await; - assert_eq!( - name(&instance_1, asset_id_1).await, - Some(String::from("Fuel Asset 1")) - ); - - assert_eq!(name(&instance_1, asset_id_2).await, None); - set_name(&instance_1, asset_id_2, String::from("Fuel Asset 2")).await; - assert_eq!( - name(&instance_1, asset_id_2).await, - Some(String::from("Fuel Asset 2")) - ); - - let asset_id_3 = get_asset_id(Bytes32::from([3u8; 32]), id); - assert_eq!(name(&instance_1, asset_id_3).await, None); - set_name(&instance_1, asset_id_3, String::from("Fuel Asset 3")).await; - assert_eq!( - name(&instance_1, asset_id_3).await, - Some(String::from("Fuel Asset 3")) - ); - - let asset_id_4 = get_asset_id(Bytes32::from([4u8; 32]), id); - assert_eq!(name(&instance_1, asset_id_4).await, None); - set_name(&instance_1, asset_id_4, String::from("Fuel Asset 4")).await; - assert_eq!( - name(&instance_1, asset_id_4).await, - Some(String::from("Fuel Asset 4")) - ); - let asset_id_5 = get_asset_id(Bytes32::from([5u8; 32]), id); - assert_eq!(name(&instance_1, asset_id_5).await, None); - set_name(&instance_1, asset_id_5, String::from("Fuel Asset 5")).await; - assert_eq!( - name(&instance_1, asset_id_5).await, - Some(String::from("Fuel Asset 5")) - ); + set_name(&instance_1, asset_id_1, Some(name_1.clone())).await; + assert_eq!(name(&instance_1, asset_id_1).await, Some(name_1)); } #[tokio::test] - async fn does_not_overwrite_other_names() { + async fn get_multiple_assets_name() { let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; let (asset_id_1, asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = - defaults(id, owner_wallet, other_wallet.clone()); + defaults(id, owner_wallet.clone(), other_wallet.clone()); + let name_1 = String::from("Fuel Asset 1"); + let name_2 = String::from("Fuel Asset 2"); + let name_3 = String::from("Fuel Asset 3 Fuel Asset 3 Fuel Asset 3 Fuel Asset 3 Fuel Asset 3 Fuel Asset 3 Fuel Asset 3 Fuel Asset 3 Fuel Asset 3 Fuel Asset 3 Fuel Asset 3 Fuel Asset 3 Fuel Asset 3 Fuel Asset 3 Fuel Asset 3"); + let name_4 = String::from("4"); + let name_5 = String::from("Fuel Asset 1"); + let asset_id_3 = get_asset_id(Bytes32::from([3u8; 32]), id); + let asset_id_4 = get_asset_id(Bytes32::from([4u8; 32]), id); + let asset_id_5 = get_asset_id(Bytes32::from([5u8; 32]), id); assert_eq!(name(&instance_1, asset_id_1).await, None); - set_name(&instance_1, asset_id_1, String::from("Fuel Asset 1")).await; - assert_eq!( - name(&instance_1, asset_id_1).await, - Some(String::from("Fuel Asset 1")) - ); - assert_eq!(name(&instance_1, asset_id_2).await, None); - set_name(&instance_1, asset_id_2, String::from("Fuel Asset 2")).await; + assert_eq!(name(&instance_1, asset_id_3).await, None); + assert_eq!(name(&instance_1, asset_id_4).await, None); + assert_eq!(name(&instance_1, asset_id_5).await, None); + + set_name(&instance_1, asset_id_1, Some(name_1.clone())).await; + set_name(&instance_1, asset_id_2, Some(name_2.clone())).await; + set_name(&instance_1, asset_id_3, Some(name_3.clone())).await; + set_name(&instance_1, asset_id_4, Some(name_4.clone())).await; + set_name(&instance_1, asset_id_5, Some(name_5.clone())).await; - assert_eq!( - name(&instance_1, asset_id_1).await, - Some(String::from("Fuel Asset 1")) - ); - assert_eq!( - name(&instance_1, asset_id_2).await, - Some(String::from("Fuel Asset 2")) - ); + assert_eq!(name(&instance_1, asset_id_1).await, Some(name_1)); + assert_eq!(name(&instance_1, asset_id_2).await, Some(name_2)); + assert_eq!(name(&instance_1, asset_id_3).await, Some(name_3)); + assert_eq!(name(&instance_1, asset_id_4).await, Some(name_4)); + assert_eq!(name(&instance_1, asset_id_5).await, Some(name_5)); } } diff --git a/tests/src/native_asset/tests/functions/set_decimals.rs b/tests/src/native_asset/tests/functions/set_decimals.rs index feef6b62..9a1e457a 100644 --- a/tests/src/native_asset/tests/functions/set_decimals.rs +++ b/tests/src/native_asset/tests/functions/set_decimals.rs @@ -1,8 +1,8 @@ use crate::native_asset::tests::utils::{ interface::{decimals, set_decimals}, - setup::{defaults, get_asset_id, setup}, + setup::{defaults, get_asset_id, setup, SetDecimalsEvent}, }; -use fuels::types::Bytes32; +use fuels::types::{Bytes32, Identity}; mod success { @@ -12,58 +12,201 @@ mod success { async fn sets_one_asset() { let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; let (asset_id_1, _asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = - defaults(id, owner_wallet, other_wallet.clone()); + defaults(id, owner_wallet.clone(), other_wallet.clone()); + let decimals_1 = 9u8; assert_eq!(decimals(&instance_1, asset_id_1).await, None); - set_decimals(&instance_1, asset_id_1, 9u8).await; - assert_eq!(decimals(&instance_1, asset_id_1).await, Some(9u8)); + let response = set_decimals(&instance_1, asset_id_1, decimals_1).await; + assert_eq!(decimals(&instance_1, asset_id_1).await, Some(decimals_1)); + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + assert_eq!( + *event, + SetDecimalsEvent { + asset: asset_id_1, + decimals: decimals_1, + sender: Identity::Address(owner_wallet.address().into()), + } + ); + } + + #[tokio::test] + async fn sets_decimals_twice() { + let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; + let (asset_id_1, _asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = + defaults(id, owner_wallet.clone(), other_wallet.clone()); + let decimals_1 = 9u8; + let decimals_2 = 8u8; + + let response = set_decimals(&instance_1, asset_id_1, decimals_1).await; + assert_eq!(decimals(&instance_1, asset_id_1).await, Some(decimals_1)); + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + assert_eq!( + *event, + SetDecimalsEvent { + asset: asset_id_1, + decimals: decimals_1, + sender: Identity::Address(owner_wallet.address().into()), + } + ); + + let response = set_decimals(&instance_1, asset_id_1, decimals_2).await; + assert_eq!(decimals(&instance_1, asset_id_1).await, Some(decimals_2)); + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + assert_eq!( + *event, + SetDecimalsEvent { + asset: asset_id_1, + decimals: decimals_2, + sender: Identity::Address(owner_wallet.address().into()), + } + ); } #[tokio::test] async fn sets_multiple_assets() { let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; let (asset_id_1, asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = - defaults(id, owner_wallet, other_wallet.clone()); + defaults(id, owner_wallet.clone(), other_wallet.clone()); + let decimals_1 = 9u8; + let decimals_2 = u8::MIN; + let decimals_3 = u8::MAX; + let decimals_4 = 16u8; + let decimals_5 = 9u8; + let asset_id_3 = get_asset_id(Bytes32::from([3u8; 32]), id); + let asset_id_4 = get_asset_id(Bytes32::from([4u8; 32]), id); + let asset_id_5 = get_asset_id(Bytes32::from([5u8; 32]), id); assert_eq!(decimals(&instance_1, asset_id_1).await, None); - set_decimals(&instance_1, asset_id_1, 9u8).await; - assert_eq!(decimals(&instance_1, asset_id_1).await, Some(9u8)); + let response = set_decimals(&instance_1, asset_id_1, decimals_1).await; + assert_eq!(decimals(&instance_1, asset_id_1).await, Some(decimals_1)); + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + assert_eq!( + *event, + SetDecimalsEvent { + asset: asset_id_1, + decimals: decimals_1, + sender: Identity::Address(owner_wallet.address().into()), + } + ); assert_eq!(decimals(&instance_1, asset_id_2).await, None); - set_decimals(&instance_1, asset_id_2, 8u8).await; - assert_eq!(decimals(&instance_1, asset_id_2).await, Some(8u8)); + let response = set_decimals(&instance_1, asset_id_2, decimals_2).await; + assert_eq!(decimals(&instance_1, asset_id_2).await, Some(decimals_2)); + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + assert_eq!( + *event, + SetDecimalsEvent { + asset: asset_id_2, + decimals: decimals_2, + sender: Identity::Address(owner_wallet.address().into()), + } + ); - let asset_id_3 = get_asset_id(Bytes32::from([3u8; 32]), id); assert_eq!(decimals(&instance_1, asset_id_3).await, None); - set_decimals(&instance_1, asset_id_3, 7u8).await; - assert_eq!(decimals(&instance_1, asset_id_3).await, Some(7u8)); + let response = set_decimals(&instance_1, asset_id_3, decimals_3).await; + assert_eq!(decimals(&instance_1, asset_id_3).await, Some(decimals_3)); + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + assert_eq!( + *event, + SetDecimalsEvent { + asset: asset_id_3, + decimals: decimals_3, + sender: Identity::Address(owner_wallet.address().into()), + } + ); - let asset_id_4 = get_asset_id(Bytes32::from([4u8; 32]), id); assert_eq!(decimals(&instance_1, asset_id_4).await, None); - set_decimals(&instance_1, asset_id_4, 6u8).await; - assert_eq!(decimals(&instance_1, asset_id_4).await, Some(6u8)); + let response = set_decimals(&instance_1, asset_id_4, decimals_4).await; + assert_eq!(decimals(&instance_1, asset_id_4).await, Some(decimals_4)); + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + assert_eq!( + *event, + SetDecimalsEvent { + asset: asset_id_4, + decimals: decimals_4, + sender: Identity::Address(owner_wallet.address().into()), + } + ); - let asset_id_5 = get_asset_id(Bytes32::from([5u8; 32]), id); assert_eq!(decimals(&instance_1, asset_id_5).await, None); - set_decimals(&instance_1, asset_id_5, 5u8).await; - assert_eq!(decimals(&instance_1, asset_id_5).await, Some(5u8)); + let response = set_decimals(&instance_1, asset_id_5, decimals_5).await; + assert_eq!(decimals(&instance_1, asset_id_5).await, Some(decimals_5)); + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + assert_eq!( + *event, + SetDecimalsEvent { + asset: asset_id_5, + decimals: decimals_5, + sender: Identity::Address(owner_wallet.address().into()), + } + ); } #[tokio::test] - async fn does_not_overwrite_other_decimals() { + async fn does_not_overwrite_other_assets() { let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; let (asset_id_1, asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = - defaults(id, owner_wallet, other_wallet.clone()); + defaults(id, owner_wallet.clone(), other_wallet.clone()); + let decimals_1 = 9u8; + let decimals_2 = 8u8; assert_eq!(decimals(&instance_1, asset_id_1).await, None); - set_decimals(&instance_1, asset_id_1, 9u8).await; - assert_eq!(decimals(&instance_1, asset_id_1).await, Some(9u8)); + let response = set_decimals(&instance_1, asset_id_1, decimals_1).await; + assert_eq!(decimals(&instance_1, asset_id_1).await, Some(decimals_1)); + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + assert_eq!( + *event, + SetDecimalsEvent { + asset: asset_id_1, + decimals: decimals_1, + sender: Identity::Address(owner_wallet.address().into()), + } + ); assert_eq!(decimals(&instance_1, asset_id_2).await, None); - set_decimals(&instance_1, asset_id_2, 8u8).await; + let response = set_decimals(&instance_1, asset_id_2, decimals_2).await; + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + assert_eq!( + *event, + SetDecimalsEvent { + asset: asset_id_2, + decimals: decimals_2, + sender: Identity::Address(owner_wallet.address().into()), + } + ); - assert_eq!(decimals(&instance_1, asset_id_1).await, Some(9u8)); - assert_eq!(decimals(&instance_1, asset_id_2).await, Some(8u8)); + assert_eq!(decimals(&instance_1, asset_id_1).await, Some(decimals_1)); + assert_eq!(decimals(&instance_1, asset_id_2).await, Some(decimals_2)); } } diff --git a/tests/src/native_asset/tests/functions/set_metadata.rs b/tests/src/native_asset/tests/functions/set_metadata.rs index 6b257ca1..84d20f45 100644 --- a/tests/src/native_asset/tests/functions/set_metadata.rs +++ b/tests/src/native_asset/tests/functions/set_metadata.rs @@ -2,7 +2,7 @@ use crate::native_asset::tests::utils::{ interface::{metadata, set_metadata}, setup::{defaults, get_asset_id, setup, Metadata, SetMetadataEvent}, }; -use fuels::types::{Bytes, Bytes32, Identity}; +use fuels::types::{Bits256, Bytes, Bytes32, Identity}; mod success { @@ -18,7 +18,13 @@ mod success { assert_eq!(metadata(&instance_1, asset_id_1, key.clone()).await, None); - let response = set_metadata(&instance_1, asset_id_1, key.clone(), metadata1.clone()).await; + let response = set_metadata( + &instance_1, + asset_id_1, + key.clone(), + Some(metadata1.clone()), + ) + .await; assert_eq!( metadata(&instance_1, asset_id_1, key.clone()).await, Some(metadata1.clone()) @@ -33,9 +39,47 @@ mod success { *event, SetMetadataEvent { asset: asset_id_1, + metadata: Some(metadata1), + key: key, + sender: Identity::Address(owner_wallet.address().into()), + } + ); + } + + #[tokio::test] + async fn sets_none() { + let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; + let (asset_id_1, _asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = + defaults(id, owner_wallet.clone(), other_wallet.clone()); + let metadata1 = Metadata::String(String::from("Fuel NFT Metadata")); + let key = String::from("key1"); + + set_metadata( + &instance_1, + asset_id_1, + key.clone(), + Some(metadata1.clone()), + ) + .await; + assert_eq!( + metadata(&instance_1, asset_id_1, key.clone()).await, + Some(metadata1.clone()) + ); + + let response = set_metadata(&instance_1, asset_id_1, key.clone(), None).await; + assert_eq!(metadata(&instance_1, asset_id_1, key.clone()).await, None); + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); + + assert_eq!( + *event, + SetMetadataEvent { + asset: asset_id_1, + metadata: None, + key: key, sender: Identity::Address(owner_wallet.address().into()), - metadata: metadata1, - key: key } ); } @@ -51,7 +95,13 @@ mod success { let key = String::from("key1"); assert_eq!(metadata(&instance_1, asset_id_1, key.clone()).await, None); - let response = set_metadata(&instance_1, asset_id_1, key.clone(), metadata1.clone()).await; + let response = set_metadata( + &instance_1, + asset_id_1, + key.clone(), + Some(metadata1.clone()), + ) + .await; assert_eq!( metadata(&instance_1, asset_id_1, key.clone()).await, Some(metadata1.clone()) @@ -66,14 +116,20 @@ mod success { *event, SetMetadataEvent { asset: asset_id_1, + metadata: Some(metadata1), + key: key.clone(), sender: Identity::Address(owner_wallet.address().into()), - metadata: metadata1, - key: key.clone() } ); assert_eq!(metadata(&instance_1, asset_id_2, key.clone()).await, None); - let response = set_metadata(&instance_1, asset_id_2, key.clone(), metadata2.clone()).await; + let response = set_metadata( + &instance_1, + asset_id_2, + key.clone(), + Some(metadata2.clone()), + ) + .await; assert_eq!( metadata(&instance_1, asset_id_2, key.clone()).await, Some(metadata2.clone()) @@ -88,15 +144,21 @@ mod success { *event, SetMetadataEvent { asset: asset_id_2, + metadata: Some(metadata2), + key: key.clone(), sender: Identity::Address(owner_wallet.address().into()), - metadata: metadata2, - key: key.clone() } ); let asset_id_3 = get_asset_id(Bytes32::from([3u8; 32]), id); assert_eq!(metadata(&instance_1, asset_id_3, key.clone()).await, None); - let response = set_metadata(&instance_1, asset_id_3, key.clone(), metadata3.clone()).await; + let response = set_metadata( + &instance_1, + asset_id_3, + key.clone(), + Some(metadata3.clone()), + ) + .await; assert_eq!( metadata(&instance_1, asset_id_3, key.clone()).await, Some(metadata3.clone()) @@ -111,15 +173,15 @@ mod success { *event, SetMetadataEvent { asset: asset_id_3, + metadata: Some(metadata3), + key: key, sender: Identity::Address(owner_wallet.address().into()), - metadata: metadata3, - key: key } ); } #[tokio::test] - async fn does_not_overwrite_other_names() { + async fn does_not_overwrite_other_assets_with_same_key() { let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; let (asset_id_1, asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = defaults(id, owner_wallet.clone(), other_wallet.clone()); @@ -127,32 +189,42 @@ mod success { let metadata2 = Metadata::String(String::from("Fuel NFT Metadata 2")); let metadata3 = Metadata::String(String::from("Fuel NFT Metadata 3")); let key = String::from("key1"); + let asset_id_3 = get_asset_id(Bytes32::from([3u8; 32]), id); assert_eq!(metadata(&instance_1, asset_id_1, key.clone()).await, None); - let response = set_metadata(&instance_1, asset_id_1, key.clone(), metadata1.clone()).await; + let response = set_metadata( + &instance_1, + asset_id_1, + key.clone(), + Some(metadata1.clone()), + ) + .await; assert_eq!( metadata(&instance_1, asset_id_1.clone(), key.clone()).await, Some(metadata1.clone()) ); - let log = response .decode_logs_with_type::() .unwrap(); let event = log.first().unwrap(); - assert_eq!( *event, SetMetadataEvent { asset: asset_id_1, + metadata: Some(metadata1.clone()), + key: key.clone(), sender: Identity::Address(owner_wallet.address().into()), - metadata: metadata1.clone(), - key: key.clone() } ); assert_eq!(metadata(&instance_1, asset_id_2, key.clone()).await, None); - let response = set_metadata(&instance_1, asset_id_2, key.clone(), metadata2.clone()).await; - + let response = set_metadata( + &instance_1, + asset_id_2, + key.clone(), + Some(metadata2.clone()), + ) + .await; assert_eq!( metadata(&instance_1, asset_id_1, key.clone()).await, Some(metadata1.clone()) @@ -161,26 +233,28 @@ mod success { metadata(&instance_1, asset_id_2, key.clone()).await, Some(metadata2.clone()) ); - let log = response .decode_logs_with_type::() .unwrap(); let event = log.first().unwrap(); - assert_eq!( *event, SetMetadataEvent { asset: asset_id_2, + metadata: Some(metadata2.clone()), + key: key.clone(), sender: Identity::Address(owner_wallet.address().into()), - metadata: metadata2.clone(), - key: key.clone() } ); - let asset_id_3 = get_asset_id(Bytes32::from([3u8; 32]), id); assert_eq!(metadata(&instance_1, asset_id_3, key.clone()).await, None); - let response = set_metadata(&instance_1, asset_id_3, key.clone(), metadata3.clone()).await; - + let response = set_metadata( + &instance_1, + asset_id_3, + key.clone(), + Some(metadata3.clone()), + ) + .await; assert_eq!( metadata(&instance_1, asset_id_1, key.clone()).await, Some(metadata1) @@ -193,19 +267,17 @@ mod success { metadata(&instance_1, asset_id_3, key.clone()).await, Some(metadata3.clone()) ); - let log = response .decode_logs_with_type::() .unwrap(); let event = log.first().unwrap(); - assert_eq!( *event, SetMetadataEvent { asset: asset_id_3, + metadata: Some(metadata3), + key: key, sender: Identity::Address(owner_wallet.address().into()), - metadata: metadata3, - key: key } ); } @@ -221,34 +293,46 @@ mod success { Bytes::from_hex_str("0101010101010101010101010101010101010101010101010101010101010101") .expect("failed to convert to bytes"), ); + let metadata4 = Metadata::B256(Bits256([1u8; 32])); let key1 = String::from("key1"); let key2 = String::from("key2"); let key3 = String::from("key3"); + let key4 = String::from("key4"); assert_eq!(metadata(&instance_1, asset_id_1, key1.clone()).await, None); - let response = set_metadata(&instance_1, asset_id_1, key1.clone(), metadata1.clone()).await; + let response = set_metadata( + &instance_1, + asset_id_1, + key1.clone(), + Some(metadata1.clone()), + ) + .await; assert_eq!( metadata(&instance_1, asset_id_1, key1.clone()).await, Some(metadata1.clone()) ); - let log = response .decode_logs_with_type::() .unwrap(); let event = log.first().unwrap(); - assert_eq!( *event, SetMetadataEvent { asset: asset_id_1, + metadata: Some(metadata1.clone()), + key: key1.clone(), sender: Identity::Address(owner_wallet.address().into()), - metadata: metadata1.clone(), - key: key1.clone() } ); assert_eq!(metadata(&instance_1, asset_id_1, key2.clone()).await, None); - let response = set_metadata(&instance_1, asset_id_1, key2.clone(), metadata2.clone()).await; + let response = set_metadata( + &instance_1, + asset_id_1, + key2.clone(), + Some(metadata2.clone()), + ) + .await; assert_eq!( metadata(&instance_1, asset_id_1, key2.clone()).await, Some(metadata2.clone()) @@ -257,50 +341,132 @@ mod success { metadata(&instance_1, asset_id_1, key1.clone()).await, Some(metadata1.clone()) ); - let log = response .decode_logs_with_type::() .unwrap(); let event = log.first().unwrap(); - assert_eq!( *event, SetMetadataEvent { asset: asset_id_1, + metadata: Some(metadata2.clone()), + key: key2.clone(), sender: Identity::Address(owner_wallet.address().into()), - metadata: metadata2.clone(), - key: key2.clone() } ); assert_eq!(metadata(&instance_1, asset_id_1, key3.clone()).await, None); - let response = set_metadata(&instance_1, asset_id_1, key3.clone(), metadata3.clone()).await; + let response = set_metadata( + &instance_1, + asset_id_1, + key3.clone(), + Some(metadata3.clone()), + ) + .await; assert_eq!( metadata(&instance_1, asset_id_1, key3.clone()).await, Some(metadata3.clone()) ); assert_eq!( metadata(&instance_1, asset_id_1, key2.clone()).await, - Some(metadata2) + Some(metadata2.clone()) ); assert_eq!( metadata(&instance_1, asset_id_1, key1.clone()).await, - Some(metadata1) + Some(metadata1.clone()) ); - let log = response .decode_logs_with_type::() .unwrap(); let event = log.first().unwrap(); + assert_eq!( + *event, + SetMetadataEvent { + asset: asset_id_1, + metadata: Some(metadata3.clone()), + key: key3.clone(), + sender: Identity::Address(owner_wallet.address().into()), + } + ); + assert_eq!(metadata(&instance_1, asset_id_1, key4.clone()).await, None); + let response = set_metadata( + &instance_1, + asset_id_1, + key4.clone(), + Some(metadata4.clone()), + ) + .await; + assert_eq!( + metadata(&instance_1, asset_id_1, key4.clone()).await, + Some(metadata4.clone()) + ); + assert_eq!( + metadata(&instance_1, asset_id_1, key3).await, + Some(metadata3) + ); + assert_eq!( + metadata(&instance_1, asset_id_1, key2).await, + Some(metadata2) + ); + assert_eq!( + metadata(&instance_1, asset_id_1, key1).await, + Some(metadata1) + ); + let log = response + .decode_logs_with_type::() + .unwrap(); + let event = log.first().unwrap(); assert_eq!( *event, SetMetadataEvent { asset: asset_id_1, + metadata: Some(metadata4), + key: key4, sender: Identity::Address(owner_wallet.address().into()), - metadata: metadata3, - key: key3 } ); } } + +mod revert { + + use super::*; + + #[tokio::test] + #[should_panic(expected = "EmptyString")] + async fn when_empty_string() { + let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; + let (asset_id_1, _asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = + defaults(id, owner_wallet.clone(), other_wallet.clone()); + let metadata1 = Metadata::String(String::from("")); + let key = String::from("key1"); + + set_metadata( + &instance_1, + asset_id_1, + key.clone(), + Some(metadata1.clone()), + ) + .await; + } + + #[tokio::test] + #[should_panic(expected = "EmptyBytes")] + async fn when_empty_bytes() { + let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; + let (asset_id_1, _asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = + defaults(id, owner_wallet.clone(), other_wallet.clone()); + let metadata1 = + Metadata::Bytes(Bytes::from_hex_str("").expect("failed to convert to bytes")); + let key = String::from("key1"); + + set_metadata( + &instance_1, + asset_id_1, + key.clone(), + Some(metadata1.clone()), + ) + .await; + } +} diff --git a/tests/src/native_asset/tests/functions/set_name.rs b/tests/src/native_asset/tests/functions/set_name.rs index b7e45ba2..03246153 100644 --- a/tests/src/native_asset/tests/functions/set_name.rs +++ b/tests/src/native_asset/tests/functions/set_name.rs @@ -1,8 +1,8 @@ use crate::native_asset::tests::utils::{ interface::{name, set_name}, - setup::{defaults, get_asset_id, setup}, + setup::{defaults, get_asset_id, setup, SetNameEvent}, }; -use fuels::types::Bytes32; +use fuels::types::{Bytes32, Identity}; mod success { @@ -12,14 +12,81 @@ mod success { async fn sets_one_asset() { let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; let (asset_id_1, _asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = - defaults(id, owner_wallet, other_wallet.clone()); + defaults(id, owner_wallet.clone(), other_wallet.clone()); + let name_1 = String::from("Fuel Asset 1"); assert_eq!(name(&instance_1, asset_id_1).await, None); - set_name(&instance_1, asset_id_1, String::from("Fuel Asset 1")).await; + let response = set_name(&instance_1, asset_id_1, Some(name_1.clone())).await; + assert_eq!(name(&instance_1, asset_id_1).await, Some(name_1.clone())); + let log = response.decode_logs_with_type::().unwrap(); + let event = log.first().unwrap(); assert_eq!( - name(&instance_1, asset_id_1).await, - Some(String::from("Fuel Asset 1")) + *event, + SetNameEvent { + asset: asset_id_1, + name: Some(name_1), + sender: Identity::Address(owner_wallet.address().into()), + } + ); + } + + #[tokio::test] + async fn sets_none() { + let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; + let (asset_id_1, _asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = + defaults(id, owner_wallet.clone(), other_wallet.clone()); + let name_1 = String::from("Fuel Asset 1"); + + set_name(&instance_1, asset_id_1, Some(name_1.clone())).await; + assert_eq!(name(&instance_1, asset_id_1).await, Some(name_1.clone())); + + let response = set_name(&instance_1, asset_id_1, None).await; + assert_eq!(name(&instance_1, asset_id_1).await, None); + let log = response.decode_logs_with_type::().unwrap(); + let event = log.first().unwrap(); + assert_eq!( + *event, + SetNameEvent { + asset: asset_id_1, + name: None, + sender: Identity::Address(owner_wallet.address().into()), + } + ); + } + + #[tokio::test] + async fn sets_name_twice() { + let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; + let (asset_id_1, _asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = + defaults(id, owner_wallet.clone(), other_wallet.clone()); + let name_1 = String::from("Fuel Asset 1"); + let name_2 = String::from("Fuel Asset 2"); + + let response = set_name(&instance_1, asset_id_1, Some(name_1.clone())).await; + assert_eq!(name(&instance_1, asset_id_1).await, Some(name_1.clone())); + let log = response.decode_logs_with_type::().unwrap(); + let event = log.first().unwrap(); + assert_eq!( + *event, + SetNameEvent { + asset: asset_id_1, + name: Some(name_1), + sender: Identity::Address(owner_wallet.address().into()), + } + ); + + let response = set_name(&instance_1, asset_id_1, Some(name_2.clone())).await; + assert_eq!(name(&instance_1, asset_id_1).await, Some(name_2.clone())); + let log = response.decode_logs_with_type::().unwrap(); + let event = log.first().unwrap(); + assert_eq!( + *event, + SetNameEvent { + asset: asset_id_1, + name: Some(name_2), + sender: Identity::Address(owner_wallet.address().into()), + } ); } @@ -27,70 +94,139 @@ mod success { async fn sets_multiple_assets() { let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; let (asset_id_1, asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = - defaults(id, owner_wallet, other_wallet.clone()); + defaults(id, owner_wallet.clone(), other_wallet.clone()); + let name_1 = String::from("Fuel Asset 1"); + let name_2 = String::from("Fuel Asset 2"); + let name_3 = String::from("Fuel Asset 3 Fuel Asset 3 Fuel Asset 3 Fuel Asset 3 Fuel Asset 3 Fuel Asset 3 Fuel Asset 3 Fuel Asset 3 Fuel Asset 3 Fuel Asset 3 Fuel Asset 3 Fuel Asset 3 Fuel Asset 3 Fuel Asset 3 Fuel Asset 3"); + let name_4 = String::from("4"); + let name_5 = String::from("Fuel Asset 1"); + let asset_id_3 = get_asset_id(Bytes32::from([3u8; 32]), id); + let asset_id_4 = get_asset_id(Bytes32::from([4u8; 32]), id); + let asset_id_5 = get_asset_id(Bytes32::from([5u8; 32]), id); assert_eq!(name(&instance_1, asset_id_1).await, None); - set_name(&instance_1, asset_id_1, String::from("Fuel Asset 1")).await; + let response = set_name(&instance_1, asset_id_1, Some(name_1.clone())).await; + assert_eq!(name(&instance_1, asset_id_1).await, Some(name_1.clone())); + let log = response.decode_logs_with_type::().unwrap(); + let event = log.first().unwrap(); assert_eq!( - name(&instance_1, asset_id_1).await, - Some(String::from("Fuel Asset 1")) + *event, + SetNameEvent { + asset: asset_id_1, + name: Some(name_1), + sender: Identity::Address(owner_wallet.address().into()), + } ); assert_eq!(name(&instance_1, asset_id_2).await, None); - set_name(&instance_1, asset_id_2, String::from("Fuel Asset 2")).await; + let response = set_name(&instance_1, asset_id_2, Some(name_2.clone())).await; + assert_eq!(name(&instance_1, asset_id_2).await, Some(name_2.clone())); + let log = response.decode_logs_with_type::().unwrap(); + let event = log.first().unwrap(); assert_eq!( - name(&instance_1, asset_id_2).await, - Some(String::from("Fuel Asset 2")) + *event, + SetNameEvent { + asset: asset_id_2, + name: Some(name_2), + sender: Identity::Address(owner_wallet.address().into()), + } ); - let asset_id_3 = get_asset_id(Bytes32::from([3u8; 32]), id); assert_eq!(name(&instance_1, asset_id_3).await, None); - set_name(&instance_1, asset_id_3, String::from("Fuel Asset 3")).await; + let response = set_name(&instance_1, asset_id_3, Some(name_3.clone())).await; + assert_eq!(name(&instance_1, asset_id_3).await, Some(name_3.clone())); + let log = response.decode_logs_with_type::().unwrap(); + let event = log.first().unwrap(); assert_eq!( - name(&instance_1, asset_id_3).await, - Some(String::from("Fuel Asset 3")) + *event, + SetNameEvent { + asset: asset_id_3, + name: Some(name_3), + sender: Identity::Address(owner_wallet.address().into()), + } ); - let asset_id_4 = get_asset_id(Bytes32::from([4u8; 32]), id); assert_eq!(name(&instance_1, asset_id_4).await, None); - set_name(&instance_1, asset_id_4, String::from("Fuel Asset 4")).await; + let response = set_name(&instance_1, asset_id_4, Some(name_4.clone())).await; + assert_eq!(name(&instance_1, asset_id_4).await, Some(name_4.clone())); + let log = response.decode_logs_with_type::().unwrap(); + let event = log.first().unwrap(); assert_eq!( - name(&instance_1, asset_id_4).await, - Some(String::from("Fuel Asset 4")) + *event, + SetNameEvent { + asset: asset_id_4, + name: Some(name_4), + sender: Identity::Address(owner_wallet.address().into()), + } ); - let asset_id_5 = get_asset_id(Bytes32::from([5u8; 32]), id); assert_eq!(name(&instance_1, asset_id_5).await, None); - set_name(&instance_1, asset_id_5, String::from("Fuel Asset 5")).await; + let response = set_name(&instance_1, asset_id_5, Some(name_5.clone())).await; + assert_eq!(name(&instance_1, asset_id_5).await, Some(name_5.clone())); + let log = response.decode_logs_with_type::().unwrap(); + let event = log.first().unwrap(); assert_eq!( - name(&instance_1, asset_id_5).await, - Some(String::from("Fuel Asset 5")) + *event, + SetNameEvent { + asset: asset_id_5, + name: Some(name_5), + sender: Identity::Address(owner_wallet.address().into()), + } ); } #[tokio::test] - async fn does_not_overwrite_other_names() { + async fn does_not_overwrite_other_assets() { let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; let (asset_id_1, asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = - defaults(id, owner_wallet, other_wallet.clone()); + defaults(id, owner_wallet.clone(), other_wallet.clone()); + let name_1 = String::from("Fuel Asset 1"); + let name_2 = String::from("Fuel Asset 2"); assert_eq!(name(&instance_1, asset_id_1).await, None); - set_name(&instance_1, asset_id_1, String::from("Fuel Asset 1")).await; + let response = set_name(&instance_1, asset_id_1, Some(name_1.clone())).await; + assert_eq!(name(&instance_1, asset_id_1).await, Some(name_1.clone())); + let log = response.decode_logs_with_type::().unwrap(); + let event = log.first().unwrap(); assert_eq!( - name(&instance_1, asset_id_1).await, - Some(String::from("Fuel Asset 1")) + *event, + SetNameEvent { + asset: asset_id_1, + name: Some(name_1.clone()), + sender: Identity::Address(owner_wallet.address().into()), + } ); assert_eq!(name(&instance_1, asset_id_2).await, None); - set_name(&instance_1, asset_id_2, String::from("Fuel Asset 2")).await; - + let response = set_name(&instance_1, asset_id_2, Some(name_2.clone())).await; + let log = response.decode_logs_with_type::().unwrap(); + let event = log.first().unwrap(); assert_eq!( - name(&instance_1, asset_id_1).await, - Some(String::from("Fuel Asset 1")) - ); - assert_eq!( - name(&instance_1, asset_id_2).await, - Some(String::from("Fuel Asset 2")) + *event, + SetNameEvent { + asset: asset_id_2, + name: Some(name_2.clone()), + sender: Identity::Address(owner_wallet.address().into()), + } ); + + assert_eq!(name(&instance_1, asset_id_1).await, Some(name_1)); + assert_eq!(name(&instance_1, asset_id_2).await, Some(name_2)); + } +} + +mod revert { + + use super::*; + + #[tokio::test] + #[should_panic(expected = "EmptyString")] + async fn when_empty_string() { + let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; + let (asset_id_1, _asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = + defaults(id, owner_wallet, other_wallet); + let name_1 = String::from(""); + + set_name(&instance_1, asset_id_1, Some(name_1)).await; } } diff --git a/tests/src/native_asset/tests/functions/set_symbol.rs b/tests/src/native_asset/tests/functions/set_symbol.rs index b46c6bce..bd18cc43 100644 --- a/tests/src/native_asset/tests/functions/set_symbol.rs +++ b/tests/src/native_asset/tests/functions/set_symbol.rs @@ -1,8 +1,8 @@ use crate::native_asset::tests::utils::{ interface::{set_symbol, symbol}, - setup::{defaults, get_asset_id, setup}, + setup::{defaults, get_asset_id, setup, SetSymbolEvent}, }; -use fuels::types::Bytes32; +use fuels::types::{Bytes32, Identity}; mod success { @@ -12,14 +12,93 @@ mod success { async fn sets_one_asset() { let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; let (asset_id_1, _asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = - defaults(id, owner_wallet, other_wallet.clone()); + defaults(id, owner_wallet.clone(), other_wallet.clone()); + let symbol_1 = String::from("FA1"); assert_eq!(symbol(&instance_1, asset_id_1).await, None); - set_symbol(&instance_1, asset_id_1, String::from("FA1")).await; + let response = set_symbol(&instance_1, asset_id_1, Some(symbol_1.clone())).await; assert_eq!( symbol(&instance_1, asset_id_1).await, - Some(String::from("FA1")) + Some(symbol_1.clone()) + ); + let log = response.decode_logs_with_type::().unwrap(); + let event = log.first().unwrap(); + assert_eq!( + *event, + SetSymbolEvent { + asset: asset_id_1, + symbol: Some(symbol_1), + sender: Identity::Address(owner_wallet.address().into()), + } + ); + } + + #[tokio::test] + async fn sets_none() { + let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; + let (asset_id_1, _asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = + defaults(id, owner_wallet.clone(), other_wallet.clone()); + let symbol_1 = String::from("FA1"); + + set_symbol(&instance_1, asset_id_1, Some(symbol_1.clone())).await; + assert_eq!( + symbol(&instance_1, asset_id_1).await, + Some(symbol_1.clone()) + ); + + let response = set_symbol(&instance_1, asset_id_1, None).await; + assert_eq!(symbol(&instance_1, asset_id_1).await, None); + let log = response.decode_logs_with_type::().unwrap(); + let event = log.first().unwrap(); + assert_eq!( + *event, + SetSymbolEvent { + asset: asset_id_1, + symbol: None, + sender: Identity::Address(owner_wallet.address().into()), + } + ); + } + + #[tokio::test] + async fn sets_symbol_twice() { + let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; + let (asset_id_1, _asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = + defaults(id, owner_wallet.clone(), other_wallet.clone()); + let symbol_1 = String::from("FA1"); + let symbol_2 = String::from("FA2"); + + let response = set_symbol(&instance_1, asset_id_1, Some(symbol_1.clone())).await; + assert_eq!( + symbol(&instance_1, asset_id_1).await, + Some(symbol_1.clone()) + ); + let log = response.decode_logs_with_type::().unwrap(); + let event = log.first().unwrap(); + assert_eq!( + *event, + SetSymbolEvent { + asset: asset_id_1, + symbol: Some(symbol_1), + sender: Identity::Address(owner_wallet.address().into()), + } + ); + + let response = set_symbol(&instance_1, asset_id_1, Some(symbol_2.clone())).await; + assert_eq!( + symbol(&instance_1, asset_id_1).await, + Some(symbol_2.clone()) + ); + let log = response.decode_logs_with_type::().unwrap(); + let event = log.first().unwrap(); + assert_eq!( + *event, + SetSymbolEvent { + asset: asset_id_1, + symbol: Some(symbol_2), + sender: Identity::Address(owner_wallet.address().into()), + } ); } @@ -27,70 +106,157 @@ mod success { async fn sets_multiple_assets() { let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; let (asset_id_1, asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = - defaults(id, owner_wallet, other_wallet.clone()); + defaults(id, owner_wallet.clone(), other_wallet.clone()); + let symbol_1 = String::from("FA1"); + let symbol_2 = String::from("FA2"); + let symbol_3 = String::from("FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1"); + let symbol_4 = String::from("F"); + let symbol_5 = String::from("FA1"); + let asset_id_3 = get_asset_id(Bytes32::from([3u8; 32]), id); + let asset_id_4 = get_asset_id(Bytes32::from([4u8; 32]), id); + let asset_id_5 = get_asset_id(Bytes32::from([5u8; 32]), id); assert_eq!(symbol(&instance_1, asset_id_1).await, None); - set_symbol(&instance_1, asset_id_1, String::from("FA1")).await; + let response = set_symbol(&instance_1, asset_id_1, Some(symbol_1.clone())).await; assert_eq!( symbol(&instance_1, asset_id_1).await, - Some(String::from("FA1")) + Some(symbol_1.clone()) + ); + let log = response.decode_logs_with_type::().unwrap(); + let event = log.first().unwrap(); + assert_eq!( + *event, + SetSymbolEvent { + asset: asset_id_1, + symbol: Some(symbol_1), + sender: Identity::Address(owner_wallet.address().into()), + } ); assert_eq!(symbol(&instance_1, asset_id_2).await, None); - set_symbol(&instance_1, asset_id_2, String::from("FA2")).await; + let response = set_symbol(&instance_1, asset_id_2, Some(symbol_2.clone())).await; assert_eq!( symbol(&instance_1, asset_id_2).await, - Some(String::from("FA2")) + Some(symbol_2.clone()) + ); + let log = response.decode_logs_with_type::().unwrap(); + let event = log.first().unwrap(); + assert_eq!( + *event, + SetSymbolEvent { + asset: asset_id_2, + symbol: Some(symbol_2), + sender: Identity::Address(owner_wallet.address().into()), + } ); - let asset_id_3 = get_asset_id(Bytes32::from([3u8; 32]), id); assert_eq!(symbol(&instance_1, asset_id_3).await, None); - set_symbol(&instance_1, asset_id_3, String::from("FA3")).await; + let response = set_symbol(&instance_1, asset_id_3, Some(symbol_3.clone())).await; assert_eq!( symbol(&instance_1, asset_id_3).await, - Some(String::from("FA3")) + Some(symbol_3.clone()) + ); + let log = response.decode_logs_with_type::().unwrap(); + let event = log.first().unwrap(); + assert_eq!( + *event, + SetSymbolEvent { + asset: asset_id_3, + symbol: Some(symbol_3), + sender: Identity::Address(owner_wallet.address().into()), + } ); - let asset_id_4 = get_asset_id(Bytes32::from([4u8; 32]), id); assert_eq!(symbol(&instance_1, asset_id_4).await, None); - set_symbol(&instance_1, asset_id_4, String::from("FA4")).await; + let response = set_symbol(&instance_1, asset_id_4, Some(symbol_4.clone())).await; assert_eq!( symbol(&instance_1, asset_id_4).await, - Some(String::from("FA4")) + Some(symbol_4.clone()) + ); + let log = response.decode_logs_with_type::().unwrap(); + let event = log.first().unwrap(); + assert_eq!( + *event, + SetSymbolEvent { + asset: asset_id_4, + symbol: Some(symbol_4), + sender: Identity::Address(owner_wallet.address().into()), + } ); - let asset_id_5 = get_asset_id(Bytes32::from([5u8; 32]), id); assert_eq!(symbol(&instance_1, asset_id_5).await, None); - set_symbol(&instance_1, asset_id_5, String::from("FA5")).await; + let response = set_symbol(&instance_1, asset_id_5, Some(symbol_5.clone())).await; assert_eq!( symbol(&instance_1, asset_id_5).await, - Some(String::from("FA5")) + Some(symbol_5.clone()) + ); + let log = response.decode_logs_with_type::().unwrap(); + let event = log.first().unwrap(); + assert_eq!( + *event, + SetSymbolEvent { + asset: asset_id_5, + symbol: Some(symbol_5), + sender: Identity::Address(owner_wallet.address().into()), + } ); } #[tokio::test] - async fn does_not_overwrite_other_symbols() { + async fn does_not_overwrite_other_assets() { let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; let (asset_id_1, asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = - defaults(id, owner_wallet, other_wallet.clone()); + defaults(id, owner_wallet.clone(), other_wallet.clone()); + let symbol_1 = String::from("FA1"); + let symbol_2 = String::from("FA2"); assert_eq!(symbol(&instance_1, asset_id_1).await, None); - set_symbol(&instance_1, asset_id_1, String::from("FA1")).await; + let response = set_symbol(&instance_1, asset_id_1, Some(symbol_1.clone())).await; assert_eq!( symbol(&instance_1, asset_id_1).await, - Some(String::from("FA1")) + Some(symbol_1.clone()) ); - - assert_eq!(symbol(&instance_1, asset_id_2).await, None); - set_symbol(&instance_1, asset_id_2, String::from("FA2")).await; - + let log = response.decode_logs_with_type::().unwrap(); + let event = log.first().unwrap(); assert_eq!( - symbol(&instance_1, asset_id_1).await, - Some(String::from("FA1")) + *event, + SetSymbolEvent { + asset: asset_id_1, + symbol: Some(symbol_1.clone()), + sender: Identity::Address(owner_wallet.address().into()), + } ); + + assert_eq!(symbol(&instance_1, asset_id_2).await, None); + let response = set_symbol(&instance_1, asset_id_2, Some(symbol_2.clone())).await; + let log = response.decode_logs_with_type::().unwrap(); + let event = log.first().unwrap(); assert_eq!( - symbol(&instance_1, asset_id_2).await, - Some(String::from("FA2")) + *event, + SetSymbolEvent { + asset: asset_id_2, + symbol: Some(symbol_2.clone()), + sender: Identity::Address(owner_wallet.address().into()), + } ); + + assert_eq!(symbol(&instance_1, asset_id_1).await, Some(symbol_1)); + assert_eq!(symbol(&instance_1, asset_id_2).await, Some(symbol_2)); + } +} + +mod revert { + + use super::*; + + #[tokio::test] + #[should_panic(expected = "EmptyString")] + async fn when_empty_string() { + let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; + let (asset_id_1, _asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = + defaults(id, owner_wallet, other_wallet); + let symbol_1 = String::from(""); + + set_symbol(&instance_1, asset_id_1, Some(symbol_1)).await; } } diff --git a/tests/src/native_asset/tests/functions/symbol.rs b/tests/src/native_asset/tests/functions/symbol.rs index b7a9eae8..1b27e473 100644 --- a/tests/src/native_asset/tests/functions/symbol.rs +++ b/tests/src/native_asset/tests/functions/symbol.rs @@ -9,88 +9,57 @@ mod success { use super::*; #[tokio::test] - async fn one_asset() { + async fn get_none_symbol() { let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; let (asset_id_1, _asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = defaults(id, owner_wallet, other_wallet.clone()); assert_eq!(symbol(&instance_1, asset_id_1).await, None); - - set_symbol(&instance_1, asset_id_1, String::from("FA1")).await; - assert_eq!( - symbol(&instance_1, asset_id_1).await, - Some(String::from("FA1")) - ); } #[tokio::test] - async fn multiple_assets() { + async fn get_one_asset_symbol() { let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; - let (asset_id_1, asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = + let (asset_id_1, _asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = defaults(id, owner_wallet, other_wallet.clone()); + let symbol_1 = String::from("FA1"); assert_eq!(symbol(&instance_1, asset_id_1).await, None); - set_symbol(&instance_1, asset_id_1, String::from("FA1")).await; - assert_eq!( - symbol(&instance_1, asset_id_1).await, - Some(String::from("FA1")) - ); - - assert_eq!(symbol(&instance_1, asset_id_2).await, None); - set_symbol(&instance_1, asset_id_2, String::from("FA2")).await; - assert_eq!( - symbol(&instance_1, asset_id_2).await, - Some(String::from("FA2")) - ); - - let asset_id_3 = get_asset_id(Bytes32::from([3u8; 32]), id); - assert_eq!(symbol(&instance_1, asset_id_3).await, None); - set_symbol(&instance_1, asset_id_3, String::from("FA3")).await; - assert_eq!( - symbol(&instance_1, asset_id_3).await, - Some(String::from("FA3")) - ); - - let asset_id_4 = get_asset_id(Bytes32::from([4u8; 32]), id); - assert_eq!(symbol(&instance_1, asset_id_4).await, None); - set_symbol(&instance_1, asset_id_4, String::from("FA4")).await; - assert_eq!( - symbol(&instance_1, asset_id_4).await, - Some(String::from("FA4")) - ); - let asset_id_5 = get_asset_id(Bytes32::from([5u8; 32]), id); - assert_eq!(symbol(&instance_1, asset_id_5).await, None); - set_symbol(&instance_1, asset_id_5, String::from("FA5")).await; - assert_eq!( - symbol(&instance_1, asset_id_5).await, - Some(String::from("FA5")) - ); + set_symbol(&instance_1, asset_id_1, Some(symbol_1.clone())).await; + assert_eq!(symbol(&instance_1, asset_id_1).await, Some(symbol_1)); } #[tokio::test] - async fn does_not_overwrite_other_symbols() { + async fn get_multiple_assets_symbols() { let (owner_wallet, other_wallet, id, instance_1, _instance_2) = setup().await; let (asset_id_1, asset_id_2, _sub_id_1, _sub_id_2, _identity1, _other_identity) = defaults(id, owner_wallet, other_wallet.clone()); + let symbol_1 = String::from("FA1"); + let symbol_2 = String::from("FA2"); + let symbol_3 = String::from("FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1FA1"); + let symbol_4 = String::from("F"); + let symbol_5 = String::from("FA1"); + let asset_id_3 = get_asset_id(Bytes32::from([3u8; 32]), id); + let asset_id_4 = get_asset_id(Bytes32::from([4u8; 32]), id); + let asset_id_5 = get_asset_id(Bytes32::from([5u8; 32]), id); assert_eq!(symbol(&instance_1, asset_id_1).await, None); - set_symbol(&instance_1, asset_id_1, String::from("FA1")).await; - assert_eq!( - symbol(&instance_1, asset_id_1).await, - Some(String::from("FA1")) - ); - assert_eq!(symbol(&instance_1, asset_id_2).await, None); - set_symbol(&instance_1, asset_id_2, String::from("FA2")).await; + assert_eq!(symbol(&instance_1, asset_id_3).await, None); + assert_eq!(symbol(&instance_1, asset_id_4).await, None); + assert_eq!(symbol(&instance_1, asset_id_5).await, None); + + set_symbol(&instance_1, asset_id_1, Some(symbol_1.clone())).await; + set_symbol(&instance_1, asset_id_2, Some(symbol_2.clone())).await; + set_symbol(&instance_1, asset_id_3, Some(symbol_3.clone())).await; + set_symbol(&instance_1, asset_id_4, Some(symbol_4.clone())).await; + set_symbol(&instance_1, asset_id_5, Some(symbol_5.clone())).await; - assert_eq!( - symbol(&instance_1, asset_id_1).await, - Some(String::from("FA1")) - ); - assert_eq!( - symbol(&instance_1, asset_id_2).await, - Some(String::from("FA2")) - ); + assert_eq!(symbol(&instance_1, asset_id_1).await, Some(symbol_1)); + assert_eq!(symbol(&instance_1, asset_id_2).await, Some(symbol_2)); + assert_eq!(symbol(&instance_1, asset_id_3).await, Some(symbol_3)); + assert_eq!(symbol(&instance_1, asset_id_4).await, Some(symbol_4)); + assert_eq!(symbol(&instance_1, asset_id_5).await, Some(symbol_5)); } } diff --git a/tests/src/native_asset/tests/functions/total_assets.rs b/tests/src/native_asset/tests/functions/total_assets.rs index a857da77..d3063348 100644 --- a/tests/src/native_asset/tests/functions/total_assets.rs +++ b/tests/src/native_asset/tests/functions/total_assets.rs @@ -16,7 +16,7 @@ mod success { assert_eq!(total_assets(&instance_1).await, 0); - mint(&instance_1, identity2, sub_id_1, 100).await; + mint(&instance_1, identity2, Some(sub_id_1), 100).await; assert_eq!(total_assets(&instance_1).await, 1); } @@ -28,19 +28,31 @@ mod success { assert_eq!(total_assets(&instance_1).await, 0); - mint(&instance_1, identity2.clone(), sub_id_1, 100).await; + mint(&instance_1, identity2.clone(), Some(sub_id_1), 100).await; assert_eq!(total_assets(&instance_1).await, 1); - mint(&instance_1, identity2.clone(), sub_id_2, 200).await; + mint(&instance_1, identity2.clone(), Some(sub_id_2), 200).await; assert_eq!(total_assets(&instance_1).await, 2); - mint(&instance_1, identity2.clone(), Bits256([3u8; 32]), 300).await; + mint( + &instance_1, + identity2.clone(), + Some(Bits256([3u8; 32])), + 300, + ) + .await; assert_eq!(total_assets(&instance_1).await, 3); - mint(&instance_1, identity2.clone(), Bits256([4u8; 32]), 400).await; + mint( + &instance_1, + identity2.clone(), + Some(Bits256([4u8; 32])), + 400, + ) + .await; assert_eq!(total_assets(&instance_1).await, 4); - mint(&instance_1, identity2, Bits256([5u8; 32]), 200).await; + mint(&instance_1, identity2, Some(Bits256([5u8; 32])), 200).await; assert_eq!(total_assets(&instance_1).await, 5); } @@ -52,13 +64,13 @@ mod success { assert_eq!(total_assets(&instance_1).await, 0); - mint(&instance_1, identity2.clone(), sub_id_1, 100).await; + mint(&instance_1, identity2.clone(), Some(sub_id_1), 100).await; assert_eq!(total_assets(&instance_1).await, 1); - mint(&instance_1, identity2.clone(), sub_id_1, 100).await; + mint(&instance_1, identity2.clone(), Some(sub_id_1), 100).await; assert_eq!(total_assets(&instance_1).await, 1); - mint(&instance_1, identity2.clone(), sub_id_1, 100).await; + mint(&instance_1, identity2.clone(), Some(sub_id_1), 100).await; assert_eq!(total_assets(&instance_1).await, 1); } } diff --git a/tests/src/native_asset/tests/functions/total_supply.rs b/tests/src/native_asset/tests/functions/total_supply.rs index d08cc37e..70bc703c 100644 --- a/tests/src/native_asset/tests/functions/total_supply.rs +++ b/tests/src/native_asset/tests/functions/total_supply.rs @@ -15,7 +15,7 @@ mod success { defaults(id, owner_wallet, other_wallet.clone()); assert_eq!(total_supply(&instance_1, asset_id_1).await, None); - mint(&instance_1, identity2, sub_id_1, 100).await; + mint(&instance_1, identity2, Some(sub_id_1), 100).await; assert_eq!(total_supply(&instance_1, asset_id_1).await, Some(100)); } @@ -26,26 +26,38 @@ mod success { defaults(id, owner_wallet, other_wallet.clone()); assert_eq!(total_supply(&instance_1, asset_id_1).await, None); - mint(&instance_1, identity2.clone(), sub_id_1, 100).await; + mint(&instance_1, identity2.clone(), Some(sub_id_1), 100).await; assert_eq!(total_supply(&instance_1, asset_id_1).await, Some(100)); assert_eq!(total_supply(&instance_1, asset_id_2).await, None); - mint(&instance_1, identity2.clone(), sub_id_2, 200).await; + mint(&instance_1, identity2.clone(), Some(sub_id_2), 200).await; assert_eq!(total_supply(&instance_1, asset_id_2).await, Some(200)); let asset_id_3 = get_asset_id(Bytes32::from([3u8; 32]), id); assert_eq!(total_supply(&instance_1, asset_id_3).await, None); - mint(&instance_1, identity2.clone(), Bits256([3u8; 32]), 300).await; + mint( + &instance_1, + identity2.clone(), + Some(Bits256([3u8; 32])), + 300, + ) + .await; assert_eq!(total_supply(&instance_1, asset_id_3).await, Some(300)); let asset_id_4 = get_asset_id(Bytes32::from([4u8; 32]), id); assert_eq!(total_supply(&instance_1, asset_id_4).await, None); - mint(&instance_1, identity2.clone(), Bits256([4u8; 32]), 400).await; + mint( + &instance_1, + identity2.clone(), + Some(Bits256([4u8; 32])), + 400, + ) + .await; assert_eq!(total_supply(&instance_1, asset_id_4).await, Some(400)); let asset_id_5 = get_asset_id(Bytes32::from([5u8; 32]), id); assert_eq!(total_supply(&instance_1, asset_id_5).await, None); - mint(&instance_1, identity2, Bits256([5u8; 32]), 500).await; + mint(&instance_1, identity2, Some(Bits256([5u8; 32])), 500).await; assert_eq!(total_supply(&instance_1, asset_id_5).await, Some(500)); } @@ -56,13 +68,13 @@ mod success { defaults(id, owner_wallet, other_wallet.clone()); assert_eq!(total_supply(&instance_1, asset_id_1).await, None); - mint(&instance_1, identity2.clone(), sub_id_1, 100).await; + mint(&instance_1, identity2.clone(), Some(sub_id_1), 100).await; assert_eq!(total_supply(&instance_1, asset_id_1).await, Some(100)); - mint(&instance_1, identity2.clone(), sub_id_2, 200).await; + mint(&instance_1, identity2.clone(), Some(sub_id_2), 200).await; assert_eq!(total_supply(&instance_1, asset_id_1).await, Some(100)); - mint(&instance_1, identity2.clone(), sub_id_2, 300).await; + mint(&instance_1, identity2.clone(), Some(sub_id_2), 300).await; assert_eq!(total_supply(&instance_1, asset_id_1).await, Some(100)); } @@ -73,7 +85,7 @@ mod success { defaults(id, owner_wallet, other_wallet.clone()); assert_eq!(total_supply(&instance_1, asset_id_1).await, None); - mint(&instance_1, identity2.clone(), sub_id_1, 100).await; + mint(&instance_1, identity2.clone(), Some(sub_id_1), 100).await; assert_eq!(total_supply(&instance_1, asset_id_1).await, Some(100)); burn(&instance_2, asset_id_1, sub_id_1, 50).await; diff --git a/tests/src/native_asset/tests/utils/interface.rs b/tests/src/native_asset/tests/utils/interface.rs index d8dba435..4b680608 100644 --- a/tests/src/native_asset/tests/utils/interface.rs +++ b/tests/src/native_asset/tests/utils/interface.rs @@ -49,7 +49,7 @@ pub(crate) async fn decimals(contract: &AssetLib, asset: AssetId pub(crate) async fn mint( contract: &AssetLib, recipient: Identity, - sub_id: Bits256, + sub_id: Option, amount: u64, ) -> FuelCallResponse<()> { contract @@ -83,7 +83,7 @@ pub(crate) async fn burn( pub(crate) async fn set_name( contract: &AssetLib, asset: AssetId, - name: String, + name: Option, ) -> FuelCallResponse<()> { contract .methods() @@ -96,7 +96,7 @@ pub(crate) async fn set_name( pub(crate) async fn set_symbol( contract: &AssetLib, asset: AssetId, - name: String, + name: Option, ) -> FuelCallResponse<()> { contract .methods() @@ -137,11 +137,11 @@ pub(crate) async fn set_metadata( contract: &AssetLib, asset: AssetId, key: String, - metadata: Metadata, + metadata: Option, ) -> FuelCallResponse<()> { contract .methods() - .set_metadata(asset, key, metadata) + .set_metadata(asset, metadata, key) .call() .await .unwrap() diff --git a/tests/src/ownership/Forc.toml b/tests/src/ownership/Forc.toml index b24ee3f3..98c47417 100644 --- a/tests/src/ownership/Forc.toml +++ b/tests/src/ownership/Forc.toml @@ -5,5 +5,5 @@ license = "Apache-2.0" name = "ownership_test" [dependencies] -standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.5.2" } +standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.6.0" } sway_libs = { path = "../../../libs" } diff --git a/tests/src/upgradability/Forc.toml b/tests/src/upgradability/Forc.toml index 02d03edb..d99cb1d1 100644 --- a/tests/src/upgradability/Forc.toml +++ b/tests/src/upgradability/Forc.toml @@ -5,5 +5,5 @@ license = "Apache-2.0" name = "upgradability_test" [dependencies] -standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.5.2" } +standards = { git = "https://github.com/FuelLabs/sway-standards", tag = "v0.6.0" } sway_libs = { path = "../../../libs" }