Summary
In cancel(), for non-proposer owners checking if the proposal is mathematically uncancellable:
let threshold: u32 = env.storage().instance().get(&DataKey::Threshold).unwrap();
let owners: Vec<Address> = env.storage().instance().get(&DataKey::Owners).unwrap();
Both use .unwrap() which will panic if instance storage has expired (TTL exhausted). This is the same pattern flagged in issue #145 for propose() and approve(). Unlike execute() which was fixed with extend_ttl, cancel() does not call extend_ttl.
Tasks
Labels: bug, forge-multisig, security
Summary
In
cancel(), for non-proposer owners checking if the proposal is mathematically uncancellable:Both use
.unwrap()which will panic if instance storage has expired (TTL exhausted). This is the same pattern flagged in issue #145 forpropose()andapprove(). Unlikeexecute()which was fixed withextend_ttl,cancel()does not callextend_ttl.Tasks
.unwrap()onDataKey::Thresholdwith.ok_or(MultisigError::NotInitialized)?.unwrap()onDataKey::Ownerswith.ok_or(MultisigError::NotInitialized)?env.storage().instance().extend_ttl(17280, 34560)at the end ofcancel()on success.unwrap()calls on instance storage reads across all contractscancel()returnsNotInitializedrather than panicking when storage is missingLabels:
bug,forge-multisig,security