> For the complete documentation index, see [llms.txt](https://docs.maple.finance/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.maple.finance/technical-resources/singletons/governor-timelock.md).

# Governor Timelock

**Overview**

* Replaces a Governor EOA with a contract-based timelock so all governor-privileged transactions execute after a delay.
* Separates responsibilities via roles and enforces a schedule → wait → execute lifecycle.
* Prevents immediate parameter and role changes. Certain meta‑changes are themselves timelocked.

**Key Roles**

* `PROPOSER_ROLE`: Schedules proposals via `scheduleProposals(...)` or `proposeRoleUpdates(...)`.
* `EXECUTOR_ROLE`: Executes queued proposals during their execution window via `executeProposals(...)`.
* `CANCELLER_ROLE`: Unschedules proposals via `unscheduleProposals(...)` (cannot unschedule role updates).
* `ROLE_ADMIN`: Proposes role changes using `proposeRoleUpdates(...)` and manages token withdrawer pending address.
* `tokenWithdrawer` (separate address): Can rescue ERC20 tokens accidentally sent to the timelock.

**Timelock Parameters**

* Defaults are set at deployment to at least `MIN_DELAY = 1 day` and `MIN_EXECUTION_WINDOW = 1 day`.
* Default parameters can be changed with `setDefaultTimelockParameters(delay, executionWindow)`. This function is `onlySelf` and must be executed via a timelocked proposal to the timelock itself.
* Per‑function overrides: `setFunctionTimelockParameters(target, selector, delay, executionWindow)` supports either both values set to zero (use defaults) or both meeting minimums. This function is `onlySelf` and must be timelocked.
* Changing a function’s timelock uses that function’s prior timelock parameters to gate the change (cannot reduce a delay instantly).

**Proposal Lifecycle**

* Schedule: `scheduleProposals(address[] targets, bytes[] data)` records proposals with `delayedUntil` and `validUntil` and computes a `proposalHash = keccak256(target, data)`.
* Role updates: Must be scheduled via `proposeRoleUpdates(bytes32[] roles, address[] accounts, bool[] shouldGrant)` (not via `scheduleProposals`). These cannot be unscheduled.
* Unschedule: `unscheduleProposals(uint256[] proposalIds)` allowed only when `isUnschedulable` is true (i.e., not role updates).
* Execute: `executeProposals(uint256[] ids, address[] targets, bytes[] data)` checks existence, timing window, and data hash, deletes the proposal, then calls the target with the exact `data`.
* Window semantics: Executable if `block.timestamp` is within `[delayedUntil, validUntil]` via `isExecutable(id)`.

**Security Notes**

* `onlySelf` gates sensitive meta‑operations (`updateRole`, timelock config), ensuring they can only be changed through the timelock.
* Binds execution to exact calldata via the stored `proposalHash`.
* Disallows scheduling to EOAs (`target.code.length > 0`).
* Role updates, once queued, cannot be unscheduled.

**Token Rescue**

* `setPendingTokenWithdrawer(new)` (ROLE\_ADMIN) → `acceptTokenWithdrawer()` (new address) establishes the token withdrawer.
* `withdrawERC20Token(token, amount)` callable only by `tokenWithdrawer` to rescue funds sent to the timelock.

**Typical Workflows**

* Schedule and execute a MapleGlobals change:
  1. `scheduleProposals([globals], [abi.encodeWithSelector(globals.setPlatformServiceFeeRate.selector, newRate)])` (PROPOSER).
  2. Wait until `isExecutable(id)` returns true within the execution window.
  3. `executeProposals([id], [globals], [encodedData])` (EXECUTOR).
* Grant `EXECUTOR_ROLE` to a new account:
  1. `proposeRoleUpdates([EXECUTOR_ROLE], [newExecutor], [true])` (ROLE\_ADMIN).
  2. After delay, `executeProposals([id], [timelock], [abi.encodeWithSelector(timelock.updateRole.selector, EXECUTOR_ROLE, newExecutor, true)])` (EXECUTOR).
* Set a per‑function override (e.g., extend delay for `globals.setPriceOracle`):
  1. Schedule `setFunctionTimelockParameters(globals, setPriceOracle.selector, 2 days, 1 day)` to the timelock (PROPOSER).
  2. Execute after the prior timelock for that function has elapsed (EXECUTOR).

**Events and Monitoring**

* `ProposalScheduled`, `ProposalExecuted`, `ProposalUnscheduled` for lifecycle transitions.
* `FunctionTimelockSet`, `DefaultTimelockSet` for configuration changes.
* `RoleUpdated` for access changes. `PendingTokenWithdrawerSet` and `TokenWithdrawerAccepted` for rescue admin.

**Deployment and Setup**

* Constructor arguments: `tokenWithdrawer`, `proposer`, `executor`, `canceller`, `roleAdmin`.
* Defaults initialize to minimums and can be increased later via timelocked calls.
* Recommended mapping:
  * Governance multisig: `PROPOSER_ROLE`, `EXECUTOR_ROLE`, `ROLE_ADMIN`.
  * Security/ops multisig: `CANCELLER_ROLE` (to unschedule non‑role proposals when needed).

**Context**

* This contract replaces a Governor EOA so that all governor‑privileged transactions are enforced to pass through a timelock.
* Pool Delegate–level timelocks (e.g., contract upgrades) remain documented separately. See `technical-resources/admin-functions/timelocks.md`.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.maple.finance/technical-resources/singletons/governor-timelock.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
