Skip to content

Commit

Permalink
Metadata (#19)
Browse files Browse the repository at this point in the history
* add metadata extension with tests

* fix clippy
  • Loading branch information
brozorec authored Jan 28, 2025
1 parent ac71efa commit 0c3d4db
Show file tree
Hide file tree
Showing 16 changed files with 556 additions and 25 deletions.
4 changes: 4 additions & 0 deletions contracts/token/fungible/src/extensions/metadata/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
mod storage;
pub use self::storage::*;

mod test;
70 changes: 70 additions & 0 deletions contracts/token/fungible/src/extensions/metadata/storage.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
use soroban_sdk::{contracttype, symbol_short, unwrap::UnwrapOptimized, Env, String, Symbol};

use crate::storage::{INSTANCE_EXTEND_AMOUNT, INSTANCE_TTL_THRESHOLD};

/// Storage key that maps to [`Metadata`]
pub const METADATA_KEY: Symbol = symbol_short!("METADATA");

/// Storage container for token metadata
#[contracttype]
pub struct Metadata {
pub decimals: u32,
pub name: String,
pub symbol: String,
}

/// Returns the token metadata such as decimals, name and symbol.
///
/// # Arguments
///
/// * `e` - Access to the Soroban environment.
pub fn get_metadata(e: &Env) -> Metadata {
e.storage().instance().get(&METADATA_KEY).unwrap_optimized()
}

/// Returns the token decimals.
///
/// # Arguments
///
/// * `e` - Access to the Soroban environment.
pub fn decimals(e: &Env) -> u32 {
get_metadata(e).decimals
}

/// Returns the token name.
///
/// # Arguments
///
/// * `e` - Access to the Soroban environment.
pub fn name(e: &Env) -> String {
get_metadata(e).name
}

/// Returns the token symbol.
///
/// # Arguments
///
/// * `e` - Access to the Soroban environment.
pub fn symbol(e: &Env) -> String {
get_metadata(e).symbol
}

/// Sets the token metadata such as decimals, name and symbol.
///
/// # Arguments
///
/// * `e` - Access to the Soroban environment.
/// * `decimals` - The number of decimals.
/// * `name` - The name of the token.
/// * `symbol` - The symbol of the token.
///
/// # Notes
///
/// **IMPORTANT**: This function lacks authorization controls. You want to
/// invoke it most likely from a constructor or from another function with
/// admin-only authorization.
pub fn set_metadata(e: &Env, decimals: u32, name: String, symbol: String) {
let metadata = Metadata { decimals, name, symbol };
e.storage().instance().extend_ttl(INSTANCE_TTL_THRESHOLD, INSTANCE_EXTEND_AMOUNT);
e.storage().instance().set(&METADATA_KEY, &metadata);
}
53 changes: 53 additions & 0 deletions contracts/token/fungible/src/extensions/metadata/test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#![cfg(test)]

use soroban_sdk::{contract, Env, String};

use crate::extensions::metadata::{decimals, name, set_metadata, symbol};

#[contract]
struct MockContract;

#[test]
fn set_and_get_metadata() {
let e = Env::default();
let address = e.register(MockContract, ());

e.as_contract(&address, || {
let test_decimals: u32 = 7;
let test_name = String::from_str(&e, "Test Token");
let test_symbol = String::from_str(&e, "TEST");

set_metadata(&e, test_decimals, test_name.clone(), test_symbol.clone());

assert_eq!(decimals(&e), test_decimals);
assert_eq!(name(&e), test_name);
assert_eq!(symbol(&e), test_symbol);
});
}

#[test]
#[should_panic]
fn get_unset_metadata() {
let e = Env::default();
let address = e.register(MockContract, ());

e.as_contract(&address, || {
decimals(&e);
});
}

#[test]
fn metadata_update() {
let e = Env::default();
let address = e.register(MockContract, ());

e.as_contract(&address, || {
set_metadata(&e, 6, String::from_str(&e, "Initial Name"), String::from_str(&e, "INI"));

set_metadata(&e, 8, String::from_str(&e, "Updated Name"), String::from_str(&e, "UPD"));

assert_eq!(decimals(&e), 8);
assert_eq!(name(&e), String::from_str(&e, "Updated Name"));
assert_eq!(symbol(&e), String::from_str(&e, "UPD"));
});
}
1 change: 1 addition & 0 deletions contracts/token/fungible/src/extensions/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod burnable;
pub mod metadata;
pub mod mintable;
12 changes: 6 additions & 6 deletions contracts/token/fungible/src/fungible.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,8 +148,8 @@ pub trait FungibleToken {
///
/// # Notes
///
/// We recommend using the [`crate::metadata::decimals()`] function from
/// the `metadata` module when implementing this function.
/// We recommend using the [`crate::metadata::decimals()`]
/// function from the `metadata` module when implementing this function.
fn decimals(e: &Env) -> u32;

/// Returns the name for this token.
Expand All @@ -160,8 +160,8 @@ pub trait FungibleToken {
///
/// # Notes
///
/// We recommend using the [`crate::metadata::name()`] function from
/// the `metadata` module when implementing this function.
/// We recommend using the [`crate::metadata::name()`] function
/// from the `metadata` module when implementing this function.
fn name(e: &Env) -> String;

/// Returns the symbol for this token.
Expand All @@ -172,8 +172,8 @@ pub trait FungibleToken {
///
/// # Notes
///
/// We recommend using the [`crate::metadata::symbol()`] function from
/// the `metadata` module when implementing this function.
/// We recommend using the [`crate::metadata::symbol()`]
/// function from the `metadata` module when implementing this function.
fn symbol(e: &Env) -> String;
}

Expand Down
2 changes: 2 additions & 0 deletions contracts/token/fungible/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,6 @@ pub mod extensions;
pub mod fungible;
pub mod storage;

pub use extensions::metadata;

mod test;
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@
},
"ext": "v0"
},
4095
518400
]
],
[
Expand Down Expand Up @@ -236,7 +236,7 @@
},
"ext": "v0"
},
4095
120960
]
],
[
Expand Down Expand Up @@ -323,7 +323,7 @@
},
"ext": "v0"
},
4095
120960
]
]
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@
},
"ext": "v0"
},
4095
518400
]
],
[
Expand Down Expand Up @@ -192,7 +192,7 @@
},
"ext": "v0"
},
4095
120960
]
],
[
Expand Down Expand Up @@ -279,7 +279,7 @@
},
"ext": "v0"
},
4095
120960
]
]
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
},
"ext": "v0"
},
4095
518400
]
],
[
Expand Down Expand Up @@ -93,7 +93,40 @@
},
"ext": "v0"
},
4095
120960
]
],
[
{
"contract_data": {
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
"key": {
"ledger_key_nonce": {
"nonce": 801925984706572462
}
},
"durability": "temporary"
}
},
[
{
"last_modified_ledger_seq": 0,
"data": {
"contract_data": {
"ext": "v0",
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
"key": {
"ledger_key_nonce": {
"nonce": 801925984706572462
}
},
"durability": "temporary",
"val": "void"
}
},
"ext": "v0"
},
6311999
]
],
[
Expand All @@ -114,7 +147,7 @@
},
"ext": "v0"
},
4095
120960
]
]
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
},
"ext": "v0"
},
4095
518400
]
],
[
Expand Down Expand Up @@ -93,7 +93,7 @@
},
"ext": "v0"
},
4095
120960
]
],
[
Expand Down Expand Up @@ -147,7 +147,7 @@
},
"ext": "v0"
},
4095
120960
]
]
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,21 @@
},
"auth": [
[],
[]
[
[
"CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
{
"function": {
"contract_fn": {
"contract_address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD2KM",
"function_name": "",
"args": []
}
},
"sub_invocations": []
}
]
]
],
"ledger": {
"protocol_version": 22,
Expand Down Expand Up @@ -62,7 +76,7 @@
},
"ext": "v0"
},
4095
518400
]
],
[
Expand Down Expand Up @@ -110,7 +124,40 @@
},
"ext": "v0"
},
4095
120960
]
],
[
{
"contract_data": {
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
"key": {
"ledger_key_nonce": {
"nonce": 801925984706572462
}
},
"durability": "temporary"
}
},
[
{
"last_modified_ledger_seq": 0,
"data": {
"contract_data": {
"ext": "v0",
"contract": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFCT4",
"key": {
"ledger_key_nonce": {
"nonce": 801925984706572462
}
},
"durability": "temporary",
"val": "void"
}
},
"ext": "v0"
},
6311999
]
],
[
Expand All @@ -131,7 +178,7 @@
},
"ext": "v0"
},
4095
120960
]
]
]
Expand Down
Loading

0 comments on commit 0c3d4db

Please sign in to comment.