Severity: Critical
The initialize function does not check whether the contract has already been initialised. An attacker can call it again to replace the admin, reset parameters, or wipe state, taking full control of the contract.
- Contract is deployed and initialised by the legitimate admin.
- Attacker calls
initialize(attacker_address). - Contract overwrites the admin with the attacker's address.
- Attacker controls all privileged functions.
pub fn initialize(env: Env, admin: Address) {
// ❌ Missing: assert!(!env.storage().persistent().has(&DataKey::Admin), "already initialized");
env.storage().persistent().set(&DataKey::Admin, &admin);
}pub fn initialize(env: Env, admin: Address) {
assert!(
!env.storage().persistent().has(&DataKey::Admin),
"already initialized" // ✅
);
env.storage().persistent().set(&DataKey::Admin, &admin);
}No separate secure crate — the fix is an inline guard.