diff --git a/contracts/src/admin.rs b/contracts/src/admin.rs index d51ac15..e52b6c3 100644 --- a/contracts/src/admin.rs +++ b/contracts/src/admin.rs @@ -1,12 +1,7 @@ //! Admin helpers – thin re-exports so other modules can import from a single place. use crate::{DataKey, Error}; -pub use crate::Error; - - -use soroban_sdk::{Address, Env, Vec}; - - +use soroban_sdk::{symbol_short, Address, Env, Vec}; /// Default rate-limit cooldown: 0 disables per-address throttling. const DEFAULT_RATE_LIMIT_MIN_LEDGERS: u32 = 0; @@ -24,16 +19,13 @@ pub fn require_admin(env: &Env) -> Result
{ let admin = get_admin(env)?; admin.require_auth(); Ok(admin) -//! Admin-managed configuration: rate-limit cooldowns (#236) and the -//! approved-token registry (#239). - - +} /// Reads the configured minimum ledger gap between rate-limited calls. pub fn rate_limit_min_ledgers(env: &Env) -> u32 { env.storage() .instance() - .get(&DataKey::RateLimitMinLedgers) + .get(&symbol_short!("lim_ledg")) .unwrap_or(DEFAULT_RATE_LIMIT_MIN_LEDGERS) } @@ -41,28 +33,28 @@ pub fn rate_limit_min_ledgers(env: &Env) -> u32 { pub fn set_rate_limit_min_ledgers(env: &Env, min_ledgers: u32) { env.storage() .instance() - .set(&DataKey::RateLimitMinLedgers, &min_ledgers); + .set(&symbol_short!("lim_ledg"), &min_ledgers); } /// Enforces a per-address cooldown of at least `min_ledgers` ledgers /// between successive calls. The last action ledger is stored under -/// `DataKey::LastAction(address)` in **temporary** storage so it +/// `(symbol_short!("lst_act"), address)` in **temporary** storage so it /// auto-expires and does not accumulate rent. pub fn rate_limit(env: &Env, caller: &Address, min_ledgers: u32) -> Result<(), Error> { if min_ledgers == 0 { return Ok(()); } - let key = DataKey::LastAction(caller.clone()); + let key = (symbol_short!("lst_act"), caller.clone()); let current = env.ledger().sequence(); if let Some(last) = env .storage() .temporary() - .get::(
event_type,
session_id,
env.ledger().timestamp(),
- payload,
+ payload.into_val(env),
),
);
}
diff --git a/contracts/src/governance.rs b/contracts/src/governance.rs
index 599192d..c9db0b4 100644
--- a/contracts/src/governance.rs
+++ b/contracts/src/governance.rs
@@ -76,11 +76,13 @@ pub fn increment_referral_session_count(env: &Env, expert: &Address) {
}
}
+const DEFAULT_REFERRAL_SESSION_LIMIT: u32 = 50;
+
/// Returns the referral commission eligibility limit for an expert.
pub fn referral_session_limit(env: &Env) -> u32 {
env.storage()
.instance()
- .get(&DataKey::ReferralSessionLimit)
+ .get(&soroban_sdk::symbol_short!("ref_lim"))
.unwrap_or(DEFAULT_REFERRAL_SESSION_LIMIT)
}
@@ -88,5 +90,5 @@ pub fn referral_session_limit(env: &Env) -> u32 {
pub fn set_referral_session_limit(env: &Env, limit: u32) {
env.storage()
.instance()
- .set(&DataKey::ReferralSessionLimit, &limit);
+ .set(&soroban_sdk::symbol_short!("ref_lim"), &limit);
}
diff --git a/contracts/src/lib.rs b/contracts/src/lib.rs
index ced5dc7..62fe715 100644
--- a/contracts/src/lib.rs
+++ b/contracts/src/lib.rs
@@ -11,6 +11,8 @@ mod errors;
mod events;
mod governance;
mod reputation;
+pub mod roles;
+pub mod timelock;
pub use bridge::BridgeError;
pub use crypto::SessionVoucher;
pub use dex::SwapPath;
@@ -66,37 +68,7 @@ const ARCHIVE_DELAY_SECS: u64 = 90 * 24 * 60 * 60;
/// Maximum number of sessions that can be archived in a single batch call.
const MAX_ARCHIVE_BATCH_SIZE: u32 = 50;
-#[contracterror]
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
-#[repr(u32)]
-pub enum Error {
- Unauthorized = 1,
- SessionNotFound = 2,
- InvalidSessionState = 3,
- InsufficientBalance = 4,
- InvalidAmount = 5,
- NotStarted = 6,
- AlreadyFinished = 7,
- DisputeNotFound = 8,
- UpgradeNotInitiated = 9,
- TimelockNotExpired = 10,
- EmptyDisputeReason = 11,
- ProtocolPaused = 12,
- ReputationTooLow = 13,
- InvalidFeeBps = 14,
- SessionExpired = 15,
- InvalidCid = 16,
- InvalidSplitBps = 17,
- DisputeWindowActive = 18,
- InvalidFeeConfig = 19,
- InsufficientTreasuryBalance = 20,
- AmountBelowMinimum = 21,
- ExpertNotRegistered = 22,
- ExpertUnavailable = 23,
- InvalidReferrer = 24,
- ReentrancyDetected = 25,
- DepositTooLow = 26,
-}
+
const REFERRAL_COMMISSION_BPS: u32 = 500; // 5% commission of expert earnings paid from platform fee
const DEFAULT_REFERRAL_SESSION_LIMIT: u32 = 50;
const DEFAULT_CANCELLATION_FEE_BPS: u32 = 500;
@@ -179,13 +151,6 @@ pub enum DataKey {
SessionCommit(BytesN<32>),
SessionCommitConsumed(BytesN<32>),
ExpertPriceFeed(Address),
- ExpertCooldownLedgers,
- ExpertCooldownUntil(Address),
- SeekerSpendingLimit(Address),
- ExpertVoucherPubkey(Address),
- VoucherNonceConsumed(Address, u64),
- ReferralSessionLimit,
- CancellationFeeBps,
}
#[contracttype]
@@ -418,6 +383,8 @@ impl SkillSphereContract {
admin.require_auth();
env.storage().instance().set(&DataKey::Admin, &admin);
+ let key = (symbol_short!("role"), admin.clone());
+ env.storage().persistent().set(&key, &roles::Role::SuperAdmin);
env.storage()
.instance()
.set(&DataKey::SessionCounter, &0u64);
@@ -440,11 +407,31 @@ impl SkillSphereContract {
.instance()
.set(&DataKey::ReentrancyLock, &false);
env.storage().instance().set(
- &DataKey::ExpertCooldownLedgers,
+ &symbol_short!("exp_cd_l"),
&disputes::DEFAULT_EXPERT_COOLDOWN_LEDGERS,
);
}
+ pub fn grant_role(env: Env, caller: Address, user: Address, role: roles::Role) -> Result<(), Error> {
+ roles::grant_role(&env, &caller, &user, role)
+ }
+
+ pub fn revoke_role(env: Env, caller: Address, user: Address) -> Result<(), Error> {
+ roles::revoke_role(&env, &caller, &user)
+ }
+
+ pub fn has_role(env: Env, user: Address, role: roles::Role) -> bool {
+ roles::has_role(&env, &user, role)
+ }
+
+ pub fn propose_admin_action(env: Env, caller: Address, action: timelock::AdminAction) -> Result