Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add event logging to SRC-20 and SRC-7 standards #130

Merged
merged 17 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 54 additions & 4 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ env:
PATH_TO_SCRIPTS: .github/scripts

jobs:
build-sway-lib:
build-sway-standards:
runs-on: ubuntu-latest

steps:
Expand Down Expand Up @@ -61,10 +61,60 @@ jobs:
run: forc fmt --path standards --check

- name: Build All Standards
run: forc build --error-on-warnings --path standards
run: forc build --error-on-warnings --path standards --release

build-examples:
runs-on: ubuntu-latest

strategy:
matrix:
project:
[
"examples/src3-mint-burn",
"examples/src5-ownership",
"examples/src6-vault",
"examples/src7-metadata",
"examples/src11-security-information",
"examples/src12-contract-factory",
"examples/src14-simple-proxy",
"examples/src20-native-asset",
]

steps:
- name: Checkout repository
uses: actions/checkout@v2

- name: Install Rust toolchain
uses: actions-rs/toolchain@v1
with:
profile: minimal
toolchain: ${{ env.RUST_VERSION }}
override: true

- name: Init cache
uses: Swatinem/rust-cache@v1

- name: Install a modern linker (mold)
uses: rui314/setup-mold@v1

- name: Force Rust to use mold globally for compilation
run: |
touch ~/.cargo/config.toml
echo "[target.x86_64-unknown-linux-gnu]" > ~/.cargo/config.toml
echo 'linker = "clang"' >> ~/.cargo/config.toml
echo 'rustflags = ["-C", "link-arg=-fuse-ld=/usr/local/bin/mold"]' >> ~/.cargo/config.toml

- name: Install rustfmt
run: rustup component add rustfmt

- name: Install Fuel toolchain
uses: FuelLabs/action-fuel-toolchain@v0.6.0
with:
name: my-toolchain
components: forc@${{ env.FORC_VERSION }}, fuel-core@${{ env.CORE_VERSION }}

- name: Check Sway Formatting Examples
run: forc fmt --path examples --check
run: forc fmt --path ${{ matrix.project }} --check

- name: Build All Examples
run: forc build --path examples
run: forc build --path ${{ matrix.project }} --release
7 changes: 3 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/).

### Added Unreleased

- Something new here 1
- Something new here 2
- [#130](https://github.com/FuelLabs/sway-standards/pull/130) Adds the `SetNameEvent`, `SetSymbolEvent`, and `SetDecimalsEvent` to the SRC-20 standard.
- [#130](https://github.com/FuelLabs/sway-standards/pull/130) Adds the `SetMetadataEvent` to the SRC-7 standard.

### Changed Unreleased

- Something changed here 1
- Something changed here 2
- [#130](https://github.com/FuelLabs/sway-standards/pull/130) Splits examples into seperate workspace projects for improved continuous integration.

### Fixed Unreleased

Expand Down
7 changes: 6 additions & 1 deletion docs/spell-check-custom-words.txt
Original file line number Diff line number Diff line change
Expand Up @@ -260,4 +260,9 @@ OGA
glTF
GLB
Uninitalized
upgradeability
upgradeability
SetMetadataEvent
SetNameEvent
SetSymbolEvent
SetDecimalsEvent
UpdateTotalSupplyEvent
87 changes: 87 additions & 0 deletions docs/src/src-20-native-asset.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,93 @@ Non-Fungible Tokens (NFT) or Non-Fungible Assets on Fuel are Native Assets and t
* Non-Fungible Assets SHALL have a total supply of one per asset.
* Non-Fungible Assets SHALL have a decimal of `0u8`.

### Logging

The following logs MUST be implemented and emitted to follow the SRC-20 standard.

* IF a value is updated via a function call, a log MUST be emitted.
* IF a value is embedded in a contract as a constant, configurable, or other manner, an event MUST be emitted at least once.

#### SetNameEvent

The `SetNameEvent` MUST be emitted when the name of an asset has updated.

There SHALL be the following fields in the `SetNameEvent` struct:

* `asset`: The `asset` field SHALL be used for the corresponding `AssetId` of the asset has been updated.
* `name`: The `name` field SHALL be used for the corresponding `Option<String>` which represents the name of the asset.
* `sender`: The `sender` field SHALL be used for the corresponding `Identity` which made the function call that has updated the name of the asset.

Example:

```sway
pub struct SetNameEvent {
pub asset: AssetId,
pub name: Option<String>,
pub sender: Identity,
}
```

#### SetSymbolEvent

The `SetSymbolEvent` MUST be emitted when the symbol of an asset has updated.

There SHALL be the following fields in the `SetSymbolEvent` struct:

* `asset`: The `asset` field SHALL be used for the corresponding `AssetId` of the asset has been updated.
* `symbol`: The `symbol` field SHALL be used for the corresponding `Option<String>` which represents the symbol of the asset.
* `sender`: The `sender` field SHALL be used for the corresponding `Identity` which made the function call that has updated the symbol of the asset.

Example:

```sway
pub struct SetSymbolEvent {
pub asset: AssetId,
pub symbol: Option<String>,
pub sender: Identity,
}
```

#### SetDecimalsEvent

The `SetDecimalsEvent` MUST be emitted when the decimals of an asset has updated.

There SHALL be the following fields in the `SetDecimalsEvent` struct:

* `asset`: The `asset` field SHALL be used for the corresponding `AssetId` of the asset has been updated.
* `decimals`: The `decimals` field SHALL be used for the corresponding `u8` which represents the decimals of the asset.
* `sender`: The `sender` field SHALL be used for the corresponding `Identity` which made the function call that has updated the decimals of the asset.

Example:

```sway
pub struct SetDecimalsEvent {
pub asset: AssetId,
pub decimals: u8,
pub sender: Identity,
}
```

#### UpdateTotalSupplyEvent

The `UpdateTotalSupplyEvent` MUST be emitted when the total supply of an asset has updated.

There SHALL be the following fields in the `UpdateTotalSupplyEvent` struct:

* `asset`: The `asset` field SHALL be used for the corresponding `AssetId` of the asset has been updated.
* `supply`: The `supply` field SHALL be used for the corresponding `u64` which represents the total supply of the asset.
* `sender`: The `sender` field SHALL be used for the corresponding `Identity` which made the function call that has updated the total supply of the asset.

Example:

```sway
pub struct UpdateTotalSupplyEvent {
pub asset: AssetId,
pub supply: u64,
pub sender: Identity,
}
```

## Rationale

As the SRC-20 Native Asset Standard leverages Native Assets on Fuel, we do not require the implementation of certain functions such as transfer or approval. This is done directly within the FuelVM and there is no smart contract that requires updating of balances. As Fuel is UTXO based, any transfer events may be indexed on transaction receipts.
Expand Down
29 changes: 29 additions & 0 deletions docs/src/src-7-asset-metadata.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,35 @@ The `String` variant SHALL be used when the stored metadata for the correspondin

This function MUST return valid metadata for the corresponding `asset` and `key`, where the data is either a `B256`, `Bytes`, `Int`, or `String` variant. If the asset does not exist or no metadata exists, the function MUST return `None`.

### Logging

The following logs MUST be implemented and emitted to follow the SRC-7 standard.

* IF a value is updated via a function call, a log MUST be emitted.
* IF a value is embedded in a contract as a constant, configurable, or other manner, an event MUST be emitted at least once.

#### SetMetadataEvent

The `SetMetadataEvent` MUST be emitted when the metadata of an asset has updated.

There SHALL be the following fields in the `SetMetadataEvent` struct:

* `asset`: The `asset` field SHALL be used for the corresponding `AssetId` of the asset has been updated.
* `metadata`: The `metadata` field SHALL be used for the corresponding `Option<Metadata>` which represents the metadata of the asset.
* `key`: The `key` field SHALL be used for the corresponding `String` which represents the key used for storing the metadata.
* `sender`: The `sender` field SHALL be used for the corresponding `Identity` which made the function call that has updated the metadata of the asset.

Example:

```sway
pub struct SetMetadataEvent {
pub asset: AssetId,
pub metadata: Option<Metadata>,
pub key: String,
pub sender: Identity,
}
```

## Rationale

The SRC-7 standard should allow for data-rich assets to interact with one another in a safe manner.
Expand Down
20 changes: 0 additions & 20 deletions examples/Forc.toml

This file was deleted.

2 changes: 2 additions & 0 deletions examples/src11-security-information/Forc.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[workspace]
members = ["hardcoded-information", "variable-information"]
2 changes: 2 additions & 0 deletions examples/src12-contract-factory/Forc.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[workspace]
members = ["with_configurables", "without_configurables"]
2 changes: 2 additions & 0 deletions examples/src14-simple-proxy/Forc.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[workspace]
members = ["owned", "minimal"]
2 changes: 2 additions & 0 deletions examples/src20-native-asset/Forc.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[workspace]
members = ["single_asset", "multi_asset"]
55 changes: 54 additions & 1 deletion examples/src20-native-asset/multi_asset/src/multi_asset.sw
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
contract;

use standards::src20::SRC20;
use standards::src20::{SetDecimalsEvent, SetNameEvent, SetSymbolEvent, SRC20, TotalSupplyEvent,};
use std::{hash::Hash, storage::storage_string::*, string::String};

storage {
Expand Down Expand Up @@ -171,3 +171,56 @@ impl SRC20 for Contract {
storage.decimals.get(asset).try_read()
}
}

abi SetSRC20Data {
#[storage(read)]
fn set_src20_data(
asset: AssetId,
total_supply: u64,
name: String,
symbol: String,
decimals: u8,
);
}

impl SetSRC20Data for Contract {
#[storage(read)]
fn set_src20_data(
asset: AssetId,
supply: u64,
name: String,
symbol: String,
decimals: u8,
) {
// NOTE: There are no checks for if the caller has permissions to update the metadata
// If this asset does not exist, revert
if storage.total_supply.get(asset).try_read().is_none() {
revert(0);
}
let sender = msg_sender().unwrap();

log(SetNameEvent {
asset,
name: Some(name),
sender,
});

log(SetSymbolEvent {
asset,
symbol: Some(symbol),
sender,
});

log(SetDecimalsEvent {
asset,
decimals,
sender,
});

log(TotalSupplyEvent {
asset,
supply,
sender,
});
}
}
40 changes: 38 additions & 2 deletions examples/src20-native-asset/single_asset/src/single_asset.sw
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
contract;

use standards::src20::SRC20;
use std::string::String;
use standards::src20::{SetDecimalsEvent, SetNameEvent, SetSymbolEvent, SRC20, TotalSupplyEvent,};
use std::{auth::msg_sender, string::String};

configurable {
/// The total supply of coins for the asset minted by this contract.
Expand Down Expand Up @@ -165,3 +165,39 @@ impl SRC20 for Contract {
}
}
}

abi EmitSRC20Events {
fn emit_src20_events();
}

impl EmitSRC20Events for Contract {
fn emit_src20_events() {
// Metadata that is stored as a configurable should only be emitted once.
let asset = AssetId::default();
let sender = msg_sender().unwrap();

log(SetNameEvent {
asset,
name: Some(String::from_ascii_str(from_str_array(NAME))),
sender,
});

log(SetSymbolEvent {
asset,
symbol: Some(String::from_ascii_str(from_str_array(SYMBOL))),
sender,
});

log(SetDecimalsEvent {
asset,
decimals: DECIMALS,
sender,
});

log(TotalSupplyEvent {
asset,
supply: TOTAL_SUPPLY,
sender,
});
}
}
2 changes: 2 additions & 0 deletions examples/src3-mint-burn/Forc.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[workspace]
members = ["single_asset", "multi_asset"]
Loading
Loading