The Mero protocol has many critical admin functions throughout the deployed contracts. To limit the risk of abuse, it is desirable for a timelock to exist on the calling of these key admin functions. Where the change is first prepared, so users can see it in advance, and then executed after a delay period. This help protects users from a malicious admin.
The Mero protocol implements this timelock via the Governance Timelock contract. Once the contracts are deployed, the admin for each contract is set to be the Governance Timelock contract. This acts as a proxy, that all admin calls must go through.
Stored in the Governance Timelock contract are a mapping of delays. The delays are set per contract, per function. So for example, there will be a specific delay set for the
addPool function of the
AddressProvider contract. These delays are a public view and can be queried by anyone:
delays(address contract, bytes4 selector) public view returns (uint64)¶
Returns the delay for the given contract and function.
contract: The address of the contract to get the delay for.
selector: The function selector of the function to get the delay for.
These delays can be set by the admin. If the delay is currently
0, then the delay update will be executed immediately. Otherwise an update to the delay for a function will need to be prepared and executed, with the delay period for the update being the same as the current delay for that function.
The admin can prepare calls through the Governance Timelock by calling the
prepareCall function. Where they can specify the target contract and data. Once a call has been prepared, it can be queried with the other prepared calls via the
pendingCalls view which returns a list of all currently pending calls.
If for some reason, the admin decides that a call should not be executed, a pending call can be cancelled by calling the
cancelCall function. This will remove the call from the pending calls list. Cancelled calls can be queried via the
Once the delay period has ellapsed, a call is considered ready. It will then show in the
readyCalls view which returns a list of all calls that are ready to be executed. When a call is ready to be executed, it can be executed by anyone. Once a call has been executed, it will stop showing in the
readyCalls view and
pendingCalls view. It will instead show in the the
executedCalls view, which returns a list of all calls that have been executed.
Some contract functions might have no delay, for example functions that are non-destructive, and require quick responses from the admin. For these functions, instead of having to prepare and execute the call in two steps, the admin can simply call
quickExecuteCall to execute the call immediately.