Skip to content

Commit 40164c8

Browse files
authored
Merge pull request #422 from Drock0/feat/operator-role
feat: add operator role for withdrawal processing separate from admin…
2 parents 3d3ed2d + 4cc7cf8 commit 40164c8

2 files changed

Lines changed: 203 additions & 103 deletions

File tree

stellar-contracts/src/lib.rs

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@ pub enum DataKey {
252252
Operator(Address),
253253
OperatorHeartbeat(Address),
254254
OperatorNonce(Address),
255+
WithdrawOperator,
255256
Denied(Address),
256257
DeniedIndex(u64),
257258
DeniedCount,
@@ -565,14 +566,34 @@ impl FiatBridge {
565566
Ok(())
566567
}
567568

568-
pub fn withdraw(env: Env, to: Address, amount: i128, token: Address) -> Result<(), Error> {
569+
pub fn withdraw(
570+
env: Env,
571+
caller: Address,
572+
to: Address,
573+
amount: i128,
574+
token: Address,
575+
) -> Result<(), Error> {
569576
env.storage().instance().extend_ttl(MIN_TTL, MAX_TTL);
570577
let admin: Address = env
571578
.storage()
572579
.instance()
573580
.get(&DataKey::Admin)
574581
.ok_or(Error::NotInitialized)?;
575-
admin.require_auth();
582+
583+
let operator: Option<Address> = env.storage().instance().get(&DataKey::WithdrawOperator);
584+
585+
if caller == admin {
586+
caller.require_auth();
587+
} else if let Some(op) = operator {
588+
if caller == op {
589+
caller.require_auth();
590+
} else {
591+
return Err(Error::Unauthorized);
592+
}
593+
} else {
594+
return Err(Error::Unauthorized);
595+
}
596+
576597
Self::require_not_paused(&env)?;
577598

578599
if amount <= 0 {
@@ -2520,6 +2541,40 @@ impl FiatBridge {
25202541
.instance()
25212542
.set(&head_key, &Option::<u64>::None);
25222543
}
2544+
2545+
// ── Single Withdraw Operator Role (Issue #118) ─────────────────────────
2546+
2547+
pub fn set_withdraw_operator(env: Env, operator: Address) -> Result<(), Error> {
2548+
env.storage().instance().extend_ttl(MIN_TTL, MAX_TTL);
2549+
let admin: Address = env
2550+
.storage()
2551+
.instance()
2552+
.get(&DataKey::Admin)
2553+
.ok_or(Error::NotInitialized)?;
2554+
admin.require_auth();
2555+
2556+
env.storage().instance().set(&DataKey::WithdrawOperator, &operator);
2557+
env.events().publish((EVENT_VERSION, Symbol::new(&env, "set_wd_op")), operator);
2558+
Ok(())
2559+
}
2560+
2561+
pub fn remove_withdraw_operator(env: Env) -> Result<(), Error> {
2562+
env.storage().instance().extend_ttl(MIN_TTL, MAX_TTL);
2563+
let admin: Address = env
2564+
.storage()
2565+
.instance()
2566+
.get(&DataKey::Admin)
2567+
.ok_or(Error::NotInitialized)?;
2568+
admin.require_auth();
2569+
2570+
env.storage().instance().remove(&DataKey::WithdrawOperator);
2571+
env.events().publish((EVENT_VERSION, Symbol::new(&env, "rm_wd_op")), ());
2572+
Ok(())
2573+
}
2574+
2575+
pub fn get_withdraw_operator(env: Env) -> Option<Address> {
2576+
env.storage().instance().get(&DataKey::WithdrawOperator)
2577+
}
25232578
}
25242579

25252580
#[cfg(any(test, feature = "testutils"))]

0 commit comments

Comments
 (0)