Timelock Contract
The TimeLock contract is designed to enhance security and transparency of contract operations. This contract serves to enforce a mandatory delay (minDelay) on the execution of scheduled actions. Contract actions are scheduled by the admin role and can be cleared by the admin role or the contract role.
// SPDX-License-Identifier: MIT
pragma solidity 0.8.21;
import '../ChallengeBase.sol';
/// @title Timelock contract
/// @author Challenge.GG
/// @dev The TimeLock contract is designed to enhance security and transparency of contract operations.
/// This contract serves to enforce a mandatory delay (minDelay) on the execution of scheduled actions.
/// Contract actions are scheduled by the admin role and can be cleared by the admin role or the contract role.
contract TimeLock {
ChallengeBase private _baseContract; // Address to base contract that handles roles, templates and other common data
uint public minDelay;
mapping(bytes32 => uint) public timestampOf;
/// Action scheduLed event
event ActionScheduled(bytes32 indexed actionId, uint executionTime, string actionName, bytes data);
/// @dev Restricted to members of the admin role.
modifier onlyAdmin()
{
require(_baseContract.isAdmin(msg.sender), "Restricted to admin");
_;
}
/// @dev Restricted to members of the Contract role.
modifier onlyContractOrAdmin()
{
require(_baseContract.isAdmin(msg.sender) || _baseContract.isContract(msg.sender), "Restricted to admin or allowed contracts");
_;
}
/// @dev Constructor
/// @param delay Delay in seconds
constructor(address baseContract, uint delay) {
require(baseContract != address(0), "Base contract address is the zero address");
require(delay > 0, "Delay too short");
_baseContract = ChallengeBase(baseContract);
minDelay = delay;
}
/// @dev Schedule an action to only be executed after the set delay
/// @param actionName Name of the action
/// @param parameters Parameters of the action
/// @param initiator Address of the initiator
/// @return actionId Id of the action
function scheduleAction(string memory actionName, bytes memory parameters, address initiator) onlyAdmin external returns (bytes32) {
bytes32 actionId = generateActionId(actionName, parameters, initiator);
require(timestampOf[actionId] == 0, "Action already scheduled");
uint executeAfter = block.timestamp + minDelay;
timestampOf[actionId] = executeAfter;
emit ActionScheduled(actionId, executeAfter, actionName, parameters);
return actionId;
}
/// @dev Sets the base contract address
/// @param baseContract Address to base contract that handles roles, templates and other common data
function setBaseContract(address baseContract) external onlyAdmin {
require(baseContract != address(0), "Base contract address is the zero address");
_baseContract = ChallengeBase(baseContract);
}
/// @dev Clear a scheduled action
/// @param actionId Id of the action
function clearAction(bytes32 actionId) onlyContractOrAdmin public {
require(timestampOf[actionId] != 0, "Action not scheduled");
require(block.timestamp >= timestampOf[actionId], "Action time not elapsed");
timestampOf[actionId] = 0;
}
/// @dev Get the execution time of an action
function getExecutionTime(bytes32 actionId) public view returns (uint) {
return timestampOf[actionId];
}
/// @dev Get the id of an action
/// @param actionName Name of the action
/// @param parameters Parameters of the action
/// @param initiator Address of the initiator
/// @return actionId Id of the actio
function generateActionId(string memory actionName, bytes memory parameters, address initiator) public pure returns (bytes32) {
return keccak256(abi.encodePacked(actionName, parameters, initiator));
}
}
Last updated