You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Reconstruct the timelock Crate: Proposer/Executor/Canceller Roles and Predecessor Dependencies #166
Description: timelock/ is empty end to end apart from a migrations shim, despite README.md describing a full delayed-execution admin with proposer/executor/canceller roles and predecessor dependencies. Rebuild the crate to match that documented design.
Problem Statement & Context:
The timelock is the mechanism meant to hold the admin role on the other contracts so users always get an exit window before a destructive admin action lands. Without it, every other contract in the protocol has a single immediately-acting admin: Address as its sole point of control — a foundational safety gap, not a nice-to-have.
Scope & Acceptance Criteria:
initialize establishing the three roles (and compatibility with common's admin/multisig pattern where applicable).
schedule/propose, execute, and cancel entrypoints with a configurable delay, role-gated per the README's table.
Predecessor dependency support: an operation with an unexecuted predecessor cannot execute.
Contract errors and lifecycle events for scheduled, executed, and cancelled operations, plus a readable operation id scheme.
The existing migrations shim is preserved and still functions.
Out of scope: assigning the timelock as admin on options_market/price_oracle/vault (separate integration issue).
Implementation Guidelines:
Key Files/Modules: timelock/src/lib.rs and its supporting types/events/error/test modules, plus the existing migrations shim.
Design/Architecture: store scheduled operations in persistent storage keyed by an operation id derived from the target, payload, and nonce; enforce roles on every entrypoint; make the delay a settable parameter with a documented minimum.
Edge Cases/Constraints: executing before the delay elapses must fail; double-execution must fail; cancelling an already-executed or nonexistent operation must fail; cancelling a predecessor should not leave a dependent operation executable; ensure the delay boundary condition (exactly at eta) is decided and tested.
Testing: unit tests for each role's authorization failures, the delay boundary (just before and exactly at eta), cancel-before-execute, execute-after-cancel, predecessor ordering (dependent blocked until predecessor executes), and re-execution rejection.
Definition of "Done":
Code written, tested, and documented.
All acceptance criteria met.
PR submitted with a clear description, passing CI, relevant screenshots/test output.
Code reviewed and approved.
Resources:
README.md (timelock/ crate section) for the documented role table and delay semantics.
@tesleem-28 has applied to work on this issue as part of the Stellar Wave Program's 10th wave.
Hello Maintainer, I carefully examined the issue and understand what the final behavior should look like. I'll work on a maintainable implementation and cover the relevant scenarios.
@josephamly36-commits has applied to work on this issue as part of the Stellar Wave Program's 10th wave.
hello mainatiner ,I would like to contribute to this issue. My experience includes application architecture, performance optimization, testing, and deployment workflows. I focus on writing maintainable and scalable code.
Congratulations, @tesleem-28! 🎉 Your application was accepted by the repo's maintainers, and the issue is due on October 22, 2026.
🧑💻 @tesleem-28: Please resolve the issue such that the repo's maintainers have enough time to review your contribution before the due date. You'll earn Points for completing the issue on-time, which will make you eligible for a share of the Stellar Wave Program's reward pool.
Warning
When opening a PR, please link it to this issue to ensure it gets tracked accurately. Points are awarded when this issue is marked as completed by the maintainer.
🤠 Repo maintainers: Please keep an eye on the contributor's progress and review their work before the due date. You can manage this issue, including adjusting its complexity and points, here.
#294 — rebuilds timelock/ to match the design README.md documents, and wires the
existing migrations shim back in.
What it does
initialize(min_delay, proposers, executors, cancellers) — one-time setup,
no admin afterwards. An empty executors list means anyone may execute a
ready operation.
schedule(proposer, calls, predecessor, salt, delay) -> id — proposer-only.
The id is sha256(xdr((calls, predecessor, salt))), so it commits to the
whole payload and hash_operation derives it off-chain, before anything is
scheduled.
execute(executor, calls, predecessor, salt) — executor-only (unless open).
The operation is identified by the content the executor repeats, which
hashes to the id that was scheduled. Every call runs in order; a revert in
any of them reverts the whole batch.
cancel(canceller, id) — canceller-only.
Self-administration through delayed operations: update_delay(u64), grant_role(Role, Address), revoke_role(Role, Address), set_open_executor(bool), and migrate(u32, u32) for the shim.
The views, events and error codes the README names, with the same numbers
(1–9, plus the migration codes 100–104 every Zenith contract carries).
Two decisions the issue asked to be pinned down
The delay boundary is inclusive. An operation may be executed at
exactly its ready-at, and not before. Both sides of the boundary are
tested.
A cancelled predecessor can never run, so neither can its dependent.
Cancelling a predecessor therefore never leaves a dependent executable —
it has to be cancelled as well, which is the one thing a canceller has to
notice.
The migrations shim
The step registry, require_current and self_migrate are untouched. The
crate now declares mod migrations;, carries the migration error variants,
writes the schema version in initialize, and dispatches the migrate
self-call — the four things the shim's own note asked for.
One thing this PR also has to carry
The workspace had no root Cargo.lock, so cargo resolved ed25519-dalek to 3.0.0 for soroban-env-host (whose >=2.0.0
requirement admits it) and the build failed with a ChaCha20Rng: CryptoRng
error before a single test could run. The lockfile pins it to the 2.x line
the workspace already asks for, which is what lets the timelock's own CI
jobs (clippy, wasm, test) build at all.
Assigning the timelock as admin on options_market / price_oracle / vault, and the handover scripts in scripts/governance/, which still speak
the old timelock interface (schedule(op_id, targets, fns, args, delay), get_proposer, get_guardian). Those scripts were already broken — the
crate was empty — and re-pointing them belongs with the integration issue.
Maintainer note: the whole-workspace fmt / clippy / wasm CI jobs
are red on main before this change, for reasons owned by other issues: price_oracle, vault and options_market are still stubs (#147, #148, #149) and streams / staking / test_adversaries do not compile. The
timelock's own gates are green.
😎 @tesleem-28: You earned 200 Points for completing this issue! Once the Wave's rewards are finalized, you'll be eligible for a percentage of the Wave's reward pool based on the percentage of total points you've earned. Learn more here. You can also Leave a review to share your experience working on this issue.
🧑💻 Repo maintainers: How'd the contributor do? Leave a review to share your experience working with them.
Activity
tesleem-28 commentedon Oct 18, 2026
@tesleem-28 has applied to work on this issue as part of the Stellar Wave Program's 10th wave.
ℹ️ Repo Maintainers: To accept this application, review their application or assign @tesleem-28 to this issue.
josephamly36-commits commentedon Oct 18, 2026
@josephamly36-commits has applied to work on this issue as part of the Stellar Wave Program's 10th wave.
ℹ️ Repo Maintainers: To accept this application, review their application or assign @josephamly36-commits to this issue.
drips-wave commentedon Oct 18, 2026
Congratulations, @tesleem-28! 🎉 Your application was accepted by the repo's maintainers, and the issue is due on October 22, 2026.
🧑💻 @tesleem-28: Please resolve the issue such that the repo's maintainers have enough time to review your contribution before the due date. You'll earn Points for completing the issue on-time, which will make you eligible for a share of the Stellar Wave Program's reward pool.
Warning
When opening a PR, please link it to this issue to ensure it gets tracked accurately. Points are awarded when this issue is marked as completed by the maintainer.
🤠 Repo maintainers: Please keep an eye on the contributor's progress and review their work before the due date. You can manage this issue, including adjusting its complexity and points, here.
🌊 Happy Wave 🌊
AminMG044 commentedon Oct 19, 2026
PR
#294 — rebuilds
timelock/to match the designREADME.mddocuments, and wires theexisting migrations shim back in.
What it does
initialize(min_delay, proposers, executors, cancellers)— one-time setup,no admin afterwards. An empty
executorslist means anyone may execute aready operation.
schedule(proposer, calls, predecessor, salt, delay) -> id— proposer-only.The id is
sha256(xdr((calls, predecessor, salt))), so it commits to thewhole payload and
hash_operationderives it off-chain, before anything isscheduled.
execute(executor, calls, predecessor, salt)— executor-only (unless open).The operation is identified by the content the executor repeats, which
hashes to the id that was scheduled. Every call runs in order; a revert in
any of them reverts the whole batch.
cancel(canceller, id)— canceller-only.update_delay(u64),grant_role(Role, Address),revoke_role(Role, Address),set_open_executor(bool), andmigrate(u32, u32)for the shim.(1–9, plus the migration codes 100–104 every Zenith contract carries).
Two decisions the issue asked to be pinned down
exactly its ready-at, and not before. Both sides of the boundary are
tested.
Cancelling a predecessor therefore never leaves a dependent executable —
it has to be cancelled as well, which is the one thing a canceller has to
notice.
The migrations shim
The step registry,
require_currentandself_migrateare untouched. Thecrate now declares
mod migrations;, carries the migration error variants,writes the schema version in
initialize, and dispatches themigrateself-call — the four things the shim's own note asked for.
One thing this PR also has to carry
The workspace had no root
Cargo.lock, socargoresolveded25519-dalekto 3.0.0 forsoroban-env-host(whose>=2.0.0requirement admits it) and the build failed with a
ChaCha20Rng: CryptoRngerror before a single test could run. The lockfile pins it to the 2.x line
the workspace already asks for, which is what lets the timelock's own CI
jobs (
clippy,wasm,test) build at all.Verification
Out of scope, as the issue says
Assigning the timelock as
adminonoptions_market/price_oracle/vault, and the handover scripts inscripts/governance/, which still speakthe old timelock interface (
schedule(op_id, targets, fns, args, delay),get_proposer,get_guardian). Those scripts were already broken — thecrate was empty — and re-pointing them belongs with the integration issue.
Maintainer note: the whole-workspace
fmt/clippy/wasmCI jobsare red on
mainbefore this change, for reasons owned by other issues:price_oracle,vaultandoptions_marketare still stubs (#147, #148,#149) and
streams/staking/test_adversariesdo not compile. Thetimelock's own gates are green.
feat(timelock): reconstruct the delayed-execution admin crate
feat(timelock): reconstruct the crate — three roles, predecessors, de…
feat(timelock): reconstruct the delayed-execution admin crate
drips-wave commentedon Oct 24, 2026
This issue has been completed by @tesleem-28 as part of the Stellar Wave Program's 10th Wave 🥳
😎 @tesleem-28: You earned 200 Points for completing this issue! Once the Wave's rewards are finalized, you'll be eligible for a percentage of the Wave's reward pool based on the percentage of total points you've earned. Learn more here. You can also Leave a review to share your experience working on this issue.
🧑💻 Repo maintainers: How'd the contributor do? Leave a review to share your experience working with them.