From 507474eedeb2436e9aca19722d9ce7182c0ab734 Mon Sep 17 00:00:00 2001 From: Alex Mootz Date: Mon, 23 Oct 2023 18:35:34 -0400 Subject: [PATCH] feat: add stellar asset extension client and fix allowance bug --- mock-sep-41/src/contract.rs | 2 - mock-sep-41/src/storage.rs | 2 +- sep-41/src/lib.rs | 105 ++++++++++++++++---- sep-41/src/testutils/mock_sep_41_token.wasm | Bin 6262 -> 6217 bytes 4 files changed, 84 insertions(+), 25 deletions(-) diff --git a/mock-sep-41/src/contract.rs b/mock-sep-41/src/contract.rs index 2184a94..109a838 100644 --- a/mock-sep-41/src/contract.rs +++ b/mock-sep-41/src/contract.rs @@ -49,8 +49,6 @@ impl MockToken { storage::bump_instance(&e); storage::set_admin(&e, &new_admin); - - TokenEvents::set_admin(&e, admin, new_admin); } } diff --git a/mock-sep-41/src/storage.rs b/mock-sep-41/src/storage.rs index 9fc44f6..c2af6d6 100644 --- a/mock-sep-41/src/storage.rs +++ b/mock-sep-41/src/storage.rs @@ -152,6 +152,6 @@ pub fn set_allowance( .unwrap_optimized(); e.storage() .temporary() - .bump(&key, expiration_ledger, ledgers_to_live); + .bump(&key, ledgers_to_live, ledgers_to_live); } } diff --git a/sep-41/src/lib.rs b/sep-41/src/lib.rs index 34fd8b3..27ed6a6 100644 --- a/sep-41/src/lib.rs +++ b/sep-41/src/lib.rs @@ -6,7 +6,7 @@ #[cfg(any(test, feature = "testutils"))] pub mod testutils; -use soroban_sdk::{contractclient, symbol_short, Address, Env, String, Symbol}; +use soroban_sdk::{contractclient, symbol_short, Address, Env, String}; /// SEP-0041 Token Standard Trait #[contractclient(name = "TokenClient")] @@ -128,41 +128,102 @@ pub trait Token { fn symbol(env: Env) -> String; } +/// Extension for functions implemented by the SEP-0041 compliant native Stellar Asset +/// Contract: https://github.com/stellar/rs-soroban-env/blob/main/soroban-env-host/src/native_contract/token/contract.rs +#[contractclient(name = "StellarAssetClient")] +pub trait StellarAssetExtension { + /// Create `amount` of tokens and assigns them to `to`. + /// + /// Requires authorization by the admin. + /// + /// # Arguments + /// + /// - `to` - The address which will receive the created tokens. + /// - `amount` - The amount of tokens to be created. + fn mint(env: Env, to: Address, amount: i128); + + /// Set the authorization status of an address to `authorize`. + /// + /// Requires authorization by the admin. + /// + /// # Arguments + /// + /// - `addr` - The address which will have their authorization modified. + /// - `authorize` - The authorization status to be set. + fn set_authorized(env: Env, addr: Address, authorize: bool); + + /// Get the authorization status of an address. + /// + /// # Arguments + /// + /// - `addr` - The address which will have their authorization status queried. + fn authorized(env: Env, addr: Address) -> bool; + + /// Clawback `amount` of tokens from `from`. + /// + /// Requires authorization by the admin. + /// + /// # Arguments + /// + /// - `from` - The address which will have their tokens clawed back. + /// - `amount` - The amount of tokens to be clawed back. + fn clawback(env: Env, from: Address, amount: i128); + + /// Set the admin address to `new_admin`. + /// + /// Requires authorization by the admin. + /// + /// # Arguments + /// + /// - `new_admin` - The address which will be set as the new admin. + fn set_admin(env: Env, new_admin: Address); + + /// Get the admin address. + fn admin(env: Env); +} + pub struct TokenEvents {} impl TokenEvents { - pub fn approve(env: &Env, from: Address, to: Address, amount: i128, expiration_ledger: u32) { - let topics = (symbol_short!("approve"), from, to); + /// Emitted when an allowance is set + /// + /// - topics - `["approve", from: Address, spender: Address]` + /// - data - `[amount: i128, live_until_ledger: u32]` + pub fn approve( + env: &Env, + from: Address, + spender: Address, + amount: i128, + expiration_ledger: u32, + ) { + let topics = (symbol_short!("approve"), from, spender); env.events().publish(topics, (amount, expiration_ledger)); } + /// Emitted when an amount is transferred from one address to another + /// + /// - topics - `["transfer", from: Address, to: Address]` + /// - data - `[amount: i128]` pub fn transfer(env: &Env, from: Address, to: Address, amount: i128) { let topics = (symbol_short!("transfer"), from, to); env.events().publish(topics, amount); } - pub fn mint(env: &Env, admin: Address, to: Address, amount: i128) { - let topics = (symbol_short!("mint"), admin, to); - env.events().publish(topics, amount); - } - - pub fn clawback(env: &Env, admin: Address, from: Address, amount: i128) { - let topics = (symbol_short!("clawback"), admin, from); + /// Emitted when an amount of tokens is burnt from one address + /// + /// - topics - `["burn", from: Address]` + /// - data - `[amount: i128]` + pub fn burn(env: &Env, from: Address, amount: i128) { + let topics = (symbol_short!("burn"), from); env.events().publish(topics, amount); } - pub fn set_authorized(env: &Env, admin: Address, id: Address, authorize: bool) { - let topics = (Symbol::new(env, "set_authorized"), admin, id); - env.events().publish(topics, authorize); - } - - pub fn set_admin(env: &Env, admin: Address, new_admin: Address) { - let topics = (symbol_short!("set_admin"), admin); - env.events().publish(topics, new_admin); - } - - pub fn burn(env: &Env, from: Address, amount: i128) { - let topics = (symbol_short!("burn"), from); + /// Emitted when an amount of tokens is created and assigned to an address + /// + /// - topics - `["mint", admin: Address, to: Address]` + /// - data - `[amount: i128]` + pub fn mint(env: &Env, admin: Address, to: Address, amount: i128) { + let topics = (symbol_short!("mint"), admin, to); env.events().publish(topics, amount); } } diff --git a/sep-41/src/testutils/mock_sep_41_token.wasm b/sep-41/src/testutils/mock_sep_41_token.wasm index 3fe6f78997e317c609fd239f9b9f08240ab3cac2..af29dfb4262e15d2a6226568a7f9a86b32c07776 100644 GIT binary patch delta 388 zcmY+7Jxjw-6o&7~y=hZo+B+zeQs`|hLey%s+Nx91LH~nGNoopBo3x}=a4L=>_`%(z zi@za*zro4b%}Ef!#Sd^0ylv^=a-MSz?|II*@nBrPO3V7qTb3)}IxBIz*9*HRE?SK{ zcE=7HE?QFtp&j&_Ziv>kSzB+0T_0@_=Qs?|W@3!#YD+nC8!g}N^wBm6Y~MwdSpU>_ zx*b%7I@;lnki{QaJ$i=`Kq*_HyFeI;ZsmatC7x3AWEWt_D=J%{Btvry zEXAV*0qPY|O^SY0Qz-bJ_5=o>PdMC1C_6(Itj; ftWY__a@aD&cX_6$N&heTop#7SQ)wti8f__m=8Rdy delta 429 zcmY+9y-EW?6ov1d*-bWVVy2X!IEg`s(HMVXk}kW2w!VPKZrniD{K!T{n*<9BMMRlS z1s_1L*+P5*v9YtTvk*bW)=qFXl0q2f-kEdm%=sSj-}%#blAS#J91$U`*;8R_bJJ_@ zI4~Wyt%lXAIxwScc~+}ab3Dk$2JKqSYd2v|vA4Yz%twOqcU92Vooc;lH9D}Uw5+BB z#ZYIjX}23t!Zj$1M;xJ7qm%v@ULxlFBf5`xE~4t8qVUj$f1z%vm=jD-hE@pnuqz5W z@1+P+5^Rj4p}8z&p1j@MeH_0&l{jHp4opo*g}G@kiN1@ZHx35hNYONK%CSf_S)fRP zb~!QFlF~IGNoXZFEGrdG