Skip to content
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
36 changes: 21 additions & 15 deletions content/stellar-contracts/access/access-control.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -46,48 +46,54 @@ Roles exist only through their relationships with accounts, so a role with zero
Here’s a simple example of using the Access Control module:

```rust
use soroban_sdk::contract, contractimpl, symbol_short, Address, Env;
use stellar_access::access_control::self as access_control, AccessControl;
use stellar_macros::has_role, only_admin;
use soroban_sdk::{contract, contractimpl, symbol_short, Address, Env};
use stellar_access::access_control::{self as access_control, AccessControl};
use stellar_macros::{has_role, only_admin};

#[contract]
pub struct MyContract;

#[contractimpl]
impl MyContract
pub fn __constructor(e: &Env, admin: Address)
impl MyContract {
pub fn __constructor(e: &Env, admin: Address) {
// Set the contract admin
access_control::set_admin(e, &admin);

// Create a "minter" role with admin as its admin
access_control::set_role_admin_no_auth(e, &symbol_short!("minter"), &symbol_short!("admin"));

}


#[only_admin]
pub fn admin_restricted_function(e: &Env) -> Vec<String>
pub fn admin_restricted_function(e: &Env) -> Vec<String> {
vec![&e, String::from_str(e, "seems sus")]

}


// we want `require_auth()` provided by the macro, since there is no
// `require_auth()` in `Base::mint`.
#[only_role(caller, "minter")]
pub fn mint(e: &Env, caller: Address, to: Address, token_id: u32)
pub fn mint(e: &Env, caller: Address, to: Address, token_id: u32) {
Base::mint(e, &to, token_id)


}


// allows either minter or burner role, does not enforce `require_auth` in the macro
#[has_any_role(caller, ["minter", "burner"])]
pub fn multi_role_action(e: &Env, caller: Address) -> String
pub fn multi_role_action(e: &Env, caller: Address) -> String {
caller.require_auth();
String::from_str(e, "multi_role_action_success")

}


// allows either minter or burner role AND enforces `require_auth` in the macro
#[only_any_role(caller, ["minter", "burner"])]
pub fn multi_role_auth_action(e: &Env, caller: Address) -> String
String::from_str(e, "multi_role_auth_action_success")

pub fn multi_role_auth_action(e: &Env, caller: Address) -> String {

String::from_str(e, "multi_role_auth_action_success")
}
}
```

## Benefits and Trade-offs
Expand Down
30 changes: 13 additions & 17 deletions content/stellar-contracts/access/ownable.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,13 @@ This feature is useful for contracts that need to become fully decentralized aft

### Procedural Macro

The module includes a procedural macro to simplify owner authorization checks:

#### @only_owner

Ensures the caller is the owner before executing the function:
The module includes the `#[only_owner]` procedural macro to simplify authorization checks by ensuring the owner is properly authorized.

```rust
#[only_owner]
pub fn restricted_function(e: &Env, other_param: u32)
pub fn restricted_function(e: &Env, other_param: u32) {
// Function body - only accessible to owner

}
```

This expands to code that retrieves the owner from storage and requires authorization before executing the function body.
Expand All @@ -49,32 +45,32 @@ This expands to code that retrieves the owner from storage and requires authoriz
Here’s a simple example of using the Ownable module:

```rust
use soroban_sdk::contract, contractimpl, Address, Env;
use stellar_access::ownable::self as ownable, Ownable;
use soroban_sdk::{contract, contractimpl, Address, Env};
use stellar_access::ownable::{self as ownable, Ownable};
use stellar_macros::only_owner;

#[contract]
pub struct MyContract;

#[contractimpl]
impl MyContract
pub fn __constructor(e: &Env, initial_owner: Address)
impl MyContract {
pub fn __constructor(e: &Env, initial_owner: Address) {
// Set the contract owner
ownable::set_owner(e, &initial_owner);

}

#[only_owner]
pub fn update_config(e: &Env, new_value: u32)
pub fn update_config(e: &Env, new_value: u32) {
// Only the owner can call this function
// Implementation...

}

// This function is accessible to anyone
pub fn get_config(e: &Env) -> u32
pub fn get_config(e: &Env) -> u32 {
// Implementation...
42


}
}
```

## Benefits and Trade-offs
Expand Down
16 changes: 8 additions & 8 deletions content/stellar-contracts/helpers/default-impl-macro.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,17 @@ developers carefully consider and explicitly define their authorization logic ra

## Usage

To use the `<mark>[default_impl]` macro, place it above the `</mark>[contractimpl]` macro when implementing one of the supported traits:
To use the `#[default_impl]` macro, place it above the `#[contractimpl]` macro when implementing one of the supported traits:

```rust
#[default_impl] // IMPORTANT: place this above `#[contractimpl]`
#[contractimpl]
impl NonFungibleToken for MyContract
impl NonFungibleToken for MyContract {
type ContractType = Base;

// Only override the methods you need to customize
// All other methods will be automatically implemented with their default behavior

}
```

## How It Works
Expand All @@ -73,7 +73,7 @@ This process ensures that all trait methods are available to the client generate
### Fungible Token Example

```rust
use soroban_sdk::contract, contractimpl, Address, Env;
use soroban_sdk::{contract, contractimpl, Address, Env};
use stellar_tokens::fungible::FungibleToken;
use stellar_macros::default_impl;

Expand All @@ -82,14 +82,14 @@ pub struct MyToken;

#[default_impl]
#[contractimpl]
impl FungibleToken for MyToken
impl FungibleToken for MyToken {
type ContractType = Base;

// Only override methods that need custom behavior
fn transfer(e: &Env, from: Address, to: Address, amount: i128)
fn transfer(e: &Env, from: Address, to: Address, amount: i128) {
// custom transfer logic here

}

// All other FungibleToken methods will be automatically implemented

}
```
25 changes: 16 additions & 9 deletions content/stellar-contracts/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,28 @@
title: Stellar Smart Contracts Suite
---

A comprehensive collection of secure, scalable smart contracts and utilities for the Stellar network,
supporting Fungible, Non-Fungible, and Multi-Token standards.
Explore our comprehensive suite of secure and scalable smart contract utilities for Stellar Soroban. Our libraries provide robust implementations for fungible and non-fungible tokens, along with powerful tools for access control and contract management.

## Tokens
Explore our implementations for token standards on Stellar Soroban:

* ***[Fungible Tokens](/stellar-contracts/tokens/fungible/fungible)***: Digital assets representing a fixed or dynamic supply of identical units.
* ***[Non-Fungible Tokens](/stellar-contracts/tokens/non-fungible/non-fungible)***: Unique digital assets with verifiable ownership.
* ***Multi-Token***: Hybrid tokens enabling both fungible and non-fungible token functionalities (work in progress).
* **[Fungible Tokens](/stellar-contracts/tokens/fungible/fungible)**: Digital assets representing a fixed or dynamic supply of identical units.
* **[Non-Fungible Tokens (NFTs)](/stellar-contracts/tokens/non-fungible/non-fungible)**: Unique digital assets with verifiable ownership.
* **Multi-Tokens**: Hybrid tokens enabling both fungible and non-fungible token functionalities (work in progress).

## Access Control

* **[Ownable](/stellar-contracts/access/ownable)**: A simple mechanism with a single account authorized for all privileged actions.
* **[Role-Based Access Control](/stellar-contracts/access/access-control)**: A flexible mechanism with distinct roles for each privileged action.

## Utilities
Discover our utility contracts for Stellar Soroban, applicable to all token standards mentioned above:

* ***[Pausable](/stellar-contracts/utils/pausable)***
* ***[Upgrades and Migrations](/stellar-contracts/utils/upgradeable)***
* **[Pausable](/stellar-contracts/utils/pausable)**: Pause and unpause contract functions, useful for emergency response.
* **[Upgradeable](/stellar-contracts/utils/upgradeable)**: Manage contract upgrades and data migrations seamlessly.
* **[Cryptography](/stellar-contracts/utils/crypto)**: A set of cryptographic primitives and utilities for Soroban contracts.

## Security and Audits

Our contracts are built with security as a top priority. You can find our audit reports [here](https://github.com/OpenZeppelin/stellar-contracts/tree/main/audits).

## Error Codes
In Stellar Soroban, each error variant is assigned an integer. To prevent duplication of error codes,
Expand Down
32 changes: 13 additions & 19 deletions content/stellar-contracts/tokens/fungible/fungible.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,17 @@ and players can transfer tokens between accounts.
Here’s what a basic fungible token contract might look like:

```rust
use soroban_sdk::contract, contractimpl, Address, Env, String;
use stellar_tokens::fungible::burnable::FungibleBurnable, Base, ContractOverrides, FungibleToken;
use stellar_access::ownable::self as ownable, Ownable;
use stellar_macros::default_impl, only_owner;
use soroban_sdk::{contract, contractimpl, Address, Env, String};
use stellar_tokens::fungible::{burnable::FungibleBurnable, Base, ContractOverrides, FungibleToken};
use stellar_access::ownable::{self as ownable, Ownable};
use stellar_macros::{default_impl, only_owner};

#[contract]
pub struct GameCurrency;

#[contractimpl]
impl GameCurrency
pub fn __constructor(e: &Env, initial_owner: Address)
impl GameCurrency {
pub fn __constructor(e: &Env, initial_owner: Address) {
// Set token metadata
Base::set_metadata(
e,
Expand All @@ -52,24 +52,24 @@ impl GameCurrency

// Set the contract owner
ownable::set_owner(e, &initial_owner);

}

#[only_owner]
pub fn mint_tokens(e: &Env, to: Address, amount: i128)
pub fn mint_tokens(e: &Env, to: Address, amount: i128) {
// Mint tokens to the recipient
Base::mint(e, &to, amount);


}
}

#[default_impl]
#[contractimpl]
impl FungibleToken for GameCurrency
impl FungibleToken for GameCurrency {
type ContractType = Base;

}

#[default_impl]
#[contractimpl]
impl FungibleBurnable for GameCurrency
impl FungibleBurnable for GameCurrency {}
```

## Extensions
Expand Down Expand Up @@ -103,12 +103,6 @@ The `FungibleBlockList` trait extends the `FungibleToken` trait to provide a blo
can be managed by an authorized account. This extension ensures that blocked accounts cannot transfer/receive
tokens, or approve token transfers.

### TokenInterface Macro

For contracts that implement both `FungibleToken` and `FungibleBurnable` and also need to implement
`soroban_sdk::token::TokenInterface`, we provide the `impl_token_interface!` macro. This macro automatically
generates the required boilerplate, simplifying the implementation process.

## Utility Modules

The package includes utility modules to help with common token implementation patterns:
Expand Down
Loading