Skip to content
Open
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
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion admin_sep/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "admin-sep"
version = "0.1.0"
version = "0.27.0"
edition = "2024"
publish = true
rust-version = "1.91.0"
Expand All @@ -20,3 +20,9 @@ soroban-sdk = { workspace = true }
[dev-dependencies]
soroban-sdk = { workspace = true, features = ["testutils"] }


# Verified by the Flux refinement checker (github.com/flux-rs/flux) via
# `cargo flux -p admin-sep` — metadata only, no dependency; inert for
# normal builds and for crates.io.
[package.metadata.flux]
enabled = true
12 changes: 12 additions & 0 deletions admin_sep/src/administratable.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,21 @@
use soroban_sdk::{Address, Env, Symbol, contracttrait, symbol_short};

/// Trait for using an admin address to control access.
///
/// # Safety invariant
///
/// The default [`Self::admin`] assumes the admin storage entry exists.
/// Consuming contracts uphold this by calling [`Self::set_admin`] from their
/// constructor (its first call skips the auth check for exactly this
/// purpose), so the entry is written before any entry point can read it.
/// A contract that adopts this trait without constructor wiring makes
/// `admin()` undefined behavior.
#[contracttrait]
pub trait Administratable {
fn admin(env: &Env) -> soroban_sdk::Address {
// SAFETY: every consuming contract stores the admin in its
// constructor (see the trait-level safety invariant), so the entry
// exists before any read.
unsafe { admin_from_storage(env).unwrap_unchecked() }

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

set_admin is called in a contracts constructor so this is safe.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed — with set_admin wired into every consuming contract's constructor (and its first call skipping the auth check for exactly that purpose), the entry always exists before a read, so the unchecked unwrap is sound in intended use. Reverted to unwrap_unchecked and moved the requirement into a trait-level Safety invariant doc + SAFETY: comment instead, so the obligation is stated where future consumers (the trait is public API) can see what they must uphold. Gates re-run: tests, clippy, cargo flux (19/19) all green.

}

Expand Down
Loading