diff --git a/CHANGELOG.md b/CHANGELOG.md index b1d3c0d..7dad81c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -50,6 +50,8 @@ Description of the upcoming release here. - [#137](https://github.com/FuelLabs/sway-standards/pull/137) Resolves warnings for SRC-6, SRC-14, and SRC-5 standard examples. - [#136](https://github.com/FuelLabs/sway-standards/pull/136) Fixes SRC14 to recommend namespacing all non-standardized storage variables under the SRC14 namespace, fixes typos, and improves markdown in docs and inline documentation. - [#142](https://github.com/FuelLabs/sway-standards/pull/142) Fixes errors in inline documentation for SRC-10, SRC-12, SRC-14, SRC-20, SRC-3, SRC-5, SRC-7 standards. +- [#151](https://github.com/FuelLabs/sway-standards/pull/151) Fixes SRC-6 standard examples conform to the latest SRC-20 spec of logging values after updates. +- [#151](https://github.com/FuelLabs/sway-standards/pull/151) Formats code of SRC-6 examples, and fixes some comments. ## [Version 0.6.0] diff --git a/examples/src6-vault/multi_asset_vault/src/main.sw b/examples/src6-vault/multi_asset_vault/src/main.sw index ac964e3..1b249ba 100644 --- a/examples/src6-vault/multi_asset_vault/src/main.sw +++ b/examples/src6-vault/multi_asset_vault/src/main.sw @@ -12,7 +12,20 @@ use std::{ string::String, }; -use standards::{src20::SRC20, src6::{Deposit, SRC6, Withdraw}}; +use standards::{ + src20::{ + SetDecimalsEvent, + SetNameEvent, + SetSymbolEvent, + SRC20, + TotalSupplyEvent, + }, + src6::{ + Deposit, + SRC6, + Withdraw, + }, +}; pub struct VaultInfo { /// Amount of assets currently managed by this vault @@ -170,6 +183,58 @@ impl SRC20 for Contract { } } +abi SetSRC20Data { + #[storage(read, write)] + fn set_src20_data( + asset: AssetId, + name: Option, + symbol: Option, + decimals: u8, + ); +} + +impl SetSRC20Data for Contract { + #[storage(read, write)] + fn set_src20_data( + asset: AssetId, + name: Option, + symbol: Option, + 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(); + + match name { + Some(unwrapped_name) => { + storage.name.get(asset).write_slice(unwrapped_name); + SetNameEvent::new(asset, name, sender).log(); + }, + None => { + let _ = storage.name.get(asset).clear(); + SetNameEvent::new(asset, name, sender).log(); + } + } + + match symbol { + Some(unwrapped_symbol) => { + storage.symbol.get(asset).write_slice(unwrapped_symbol); + SetSymbolEvent::new(asset, symbol, sender).log(); + }, + None => { + let _ = storage.symbol.get(asset).clear(); + SetSymbolEvent::new(asset, symbol, sender).log(); + } + } + + storage.decimals.get(asset).write(decimals); + SetDecimalsEvent::new(asset, decimals, sender).log(); + } +} + /// Returns the vault shares assetid and subid for the given assets assetid and the vaults sub id fn vault_asset_id(asset: AssetId, vault_sub_id: SubId) -> (AssetId, SubId) { let share_asset_vault_sub_id = sha256((asset, vault_sub_id)); @@ -229,10 +294,11 @@ pub fn _mint( if supply.is_none() { storage.total_assets.write(storage.total_assets.read() + 1); } - storage - .total_supply - .insert(asset_id, supply.unwrap_or(0) + amount); + let new_supply = supply.unwrap_or(0) + amount; + storage.total_supply.insert(asset_id, new_supply); mint_to(recipient, vault_sub_id, amount); + TotalSupplyEvent::new(asset_id, new_supply, msg_sender().unwrap()) + .log(); } #[storage(read, write)] @@ -245,6 +311,9 @@ pub fn _burn(asset_id: AssetId, vault_sub_id: SubId, amount: u64) { ); // If we pass the check above, we can assume it is safe to unwrap. let supply = storage.total_supply.get(asset_id).try_read().unwrap(); - storage.total_supply.insert(asset_id, supply - amount); + let new_supply = supply - amount; + storage.total_supply.insert(asset_id, new_supply); burn(vault_sub_id, amount); + TotalSupplyEvent::new(asset_id, new_supply, msg_sender().unwrap()) + .log(); } diff --git a/examples/src6-vault/single_asset_single_sub_vault/src/main.sw b/examples/src6-vault/single_asset_single_sub_vault/src/main.sw index 32a43b9..b07c572 100644 --- a/examples/src6-vault/single_asset_single_sub_vault/src/main.sw +++ b/examples/src6-vault/single_asset_single_sub_vault/src/main.sw @@ -12,7 +12,20 @@ use std::{ string::String, }; -use standards::{src20::SRC20, src6::{Deposit, SRC6, Withdraw}}; +use standards::{ + src20::{ + SetDecimalsEvent, + SetNameEvent, + SetSymbolEvent, + SRC20, + TotalSupplyEvent, + }, + src6::{ + Deposit, + SRC6, + Withdraw, + }, +}; configurable { /// The only sub vault that can be deposited and withdrawn from this vault. @@ -25,6 +38,12 @@ storage { managed_assets: u64 = 0, /// The total amount of shares minted by this vault. total_supply: u64 = 0, + /// The name of a specific asset minted by this contract. + name: StorageString = StorageString {}, + /// The symbol of a specific asset minted by this contract. + symbol: StorageString = StorageString {}, + /// The decimals of a specific asset minted by this contract. + decimals: u8 = 9, } impl SRC6 for Contract { @@ -153,7 +172,10 @@ impl SRC20 for Contract { #[storage(read)] fn name(asset: AssetId) -> Option { if asset == vault_assetid() { - Some(String::from_ascii_str("Vault Shares")) + match storage.name.read_slice() { + Some(name) => Some(name), + None => None, + } } else { None } @@ -162,7 +184,10 @@ impl SRC20 for Contract { #[storage(read)] fn symbol(asset: AssetId) -> Option { if asset == vault_assetid() { - Some(String::from_ascii_str("VLTSHR")) + match storage.symbol.read_slice() { + Some(symbol) => Some(symbol), + None => None, + } } else { None } @@ -171,13 +196,62 @@ impl SRC20 for Contract { #[storage(read)] fn decimals(asset: AssetId) -> Option { if asset == vault_assetid() { - Some(9_u8) + Some(storage.decimals.read()) } else { None } } } +abi SetSRC20Data { + #[storage(read, write)] + fn set_src20_data( + asset: AssetId, + name: Option, + symbol: Option, + decimals: u8, + ); +} + +impl SetSRC20Data for Contract { + #[storage(read, write)] + fn set_src20_data( + asset: AssetId, + name: Option, + symbol: Option, + decimals: u8, + ) { + // NOTE: There are no checks for if the caller has permissions to update the metadata + require(asset == vault_assetid(), "INVALID_ASSET_ID"); + let sender = msg_sender().unwrap(); + + match name { + Some(unwrapped_name) => { + storage.name.write_slice(unwrapped_name); + SetNameEvent::new(asset, name, sender).log(); + }, + None => { + let _ = storage.name.clear(); + SetNameEvent::new(asset, name, sender).log(); + } + } + + match symbol { + Some(unwrapped_symbol) => { + storage.symbol.write_slice(unwrapped_symbol); + SetSymbolEvent::new(asset, symbol, sender).log(); + }, + None => { + let _ = storage.symbol.clear(); + SetSymbolEvent::new(asset, symbol, sender).log(); + } + } + + storage.decimals.write(decimals); + SetDecimalsEvent::new(asset, decimals, sender).log(); + } +} + /// Returns the vault shares assetid for the given assets assetid and the vaults sub id fn vault_assetid() -> AssetId { let share_asset_id = AssetId::new(ContractId::this(), PRE_CALCULATED_SHARE_VAULT_SUB_ID); @@ -209,8 +283,11 @@ pub fn _mint(recipient: Identity, amount: u64) { use std::asset::mint_to; let supply = storage.total_supply.read(); - storage.total_supply.write(supply + amount); + let new_supply = supply + amount; + storage.total_supply.write(new_supply); mint_to(recipient, PRE_CALCULATED_SHARE_VAULT_SUB_ID, amount); + TotalSupplyEvent::new(vault_assetid(), new_supply, msg_sender().unwrap()) + .log(); } #[storage(read, write)] @@ -223,6 +300,9 @@ pub fn _burn(asset_id: AssetId, amount: u64) { ); // If we pass the check above, we can assume it is safe to unwrap. let supply = storage.total_supply.read(); - storage.total_supply.write(supply - amount); + let new_supply = supply - amount; + storage.total_supply.write(new_supply); burn(PRE_CALCULATED_SHARE_VAULT_SUB_ID, amount); + TotalSupplyEvent::new(vault_assetid(), new_supply, msg_sender().unwrap()) + .log(); } diff --git a/examples/src6-vault/single_asset_vault/src/main.sw b/examples/src6-vault/single_asset_vault/src/main.sw index 2a282b5..9ad6407 100644 --- a/examples/src6-vault/single_asset_vault/src/main.sw +++ b/examples/src6-vault/single_asset_vault/src/main.sw @@ -12,7 +12,20 @@ use std::{ string::String, }; -use standards::{src20::SRC20, src6::{Deposit, SRC6, Withdraw}}; +use standards::{ + src20::{ + SetDecimalsEvent, + SetNameEvent, + SetSymbolEvent, + SRC20, + TotalSupplyEvent, + }, + src6::{ + Deposit, + SRC6, + Withdraw, + }, +}; pub struct VaultInfo { /// Amount of assets currently managed by this vault @@ -150,7 +163,7 @@ impl SRC6 for Contract { underlying_asset == AssetId::base(), storage.vault_info.get(vault_share_asset).try_read(), ) { - // In this implementation managed_assets and max_withdrawable are the same. However in case of lending out of assets, total_assets should be greater than max_withdrawable. + // In this implementation managed_assets and max_withdrawable are the same. However in case of lending out of assets, managed_assets should be greater than max_withdrawable. (true, Some(vault_info)) => Some(vault_info.managed_assets), _ => None, } @@ -184,6 +197,58 @@ impl SRC20 for Contract { } } +abi SetSRC20Data { + #[storage(read, write)] + fn set_src20_data( + asset: AssetId, + name: Option, + symbol: Option, + decimals: u8, + ); +} + +impl SetSRC20Data for Contract { + #[storage(read, write)] + fn set_src20_data( + asset: AssetId, + name: Option, + symbol: Option, + 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(); + + match name { + Some(unwrapped_name) => { + storage.name.get(asset).write_slice(unwrapped_name); + SetNameEvent::new(asset, name, sender).log(); + }, + None => { + let _ = storage.name.get(asset).clear(); + SetNameEvent::new(asset, name, sender).log(); + } + } + + match symbol { + Some(unwrapped_symbol) => { + storage.symbol.get(asset).write_slice(unwrapped_symbol); + SetSymbolEvent::new(asset, symbol, sender).log(); + }, + None => { + let _ = storage.symbol.get(asset).clear(); + SetSymbolEvent::new(asset, symbol, sender).log(); + } + } + + storage.decimals.get(asset).write(decimals); + SetDecimalsEvent::new(asset, decimals, sender).log(); + } +} + /// Returns the vault shares assetid and subid for the given assets assetid and the vaults sub id fn vault_asset_id(underlying_asset: AssetId, vault_sub_id: SubId) -> (AssetId, SubId) { let share_asset_vault_sub_id = sha256((underlying_asset, vault_sub_id)); @@ -243,11 +308,11 @@ pub fn _mint( if supply.is_none() { storage.total_assets.write(storage.total_assets.read() + 1); } - let current_supply = supply.unwrap_or(0); - storage - .total_supply - .insert(asset_id, current_supply + amount); + let new_supply = supply.unwrap_or(0) + amount; + storage.total_supply.insert(asset_id, new_supply); mint_to(recipient, vault_sub_id, amount); + TotalSupplyEvent::new(asset_id, new_supply, msg_sender().unwrap()) + .log(); } #[storage(read, write)] @@ -260,6 +325,9 @@ pub fn _burn(asset_id: AssetId, vault_sub_id: SubId, amount: u64) { ); // If we pass the check above, we can assume it is safe to unwrap. let supply = storage.total_supply.get(asset_id).try_read().unwrap(); - storage.total_supply.insert(asset_id, supply - amount); + let new_supply = supply - amount; + storage.total_supply.insert(asset_id, new_supply); burn(vault_sub_id, amount); + TotalSupplyEvent::new(asset_id, new_supply, msg_sender().unwrap()) + .log(); }