Task Manager Interface (ITaskManager
)
The ITaskManager
interface provides the core functionality for scheduling, managing, and executing automated tasks on the Monad blockchain. Developers interact primarily with this interface to schedule tasks, while Executors use it to execute pending tasks.
The Task Manager implementation utilizes non-reentrancy guards (withLock
modifier) on critical state-changing functions like scheduleTask
and executeTasks
to prevent potential exploits involving nested or overlapping calls.
Core Functions
scheduleTask
function scheduleTask(
address implementation,
uint256 taskGasLimit,
uint64 targetBlock,
uint256 maxPayment,
bytes calldata taskCallData
) external payable returns (bool scheduled, uint256 executionCost, bytes32 taskId);
Schedules a task for execution at a future targetBlock
, paying the execution cost with native MON sent in msg.value
.
- The
implementation
address is the contract containing the task logic. The Task Manager deploys a task-specific proxy (mimic) which will delegatecall
this implementation
.
- Requires sufficient
msg.value
(MON) to cover the returned executionCost
.
- Parameters
- Return Values
- Usage Example
Name | Type | Description |
---|
implementation | address | The contract address containing the task logic. A task-specific proxy deployed by the Task Manager will delegatecall this contract's code during execution. |
taskGasLimit | uint256 | The gas limit allocated for the task's execution logic within the implementation . Determines the task size category (Small, Medium, Large). |
targetBlock | uint64 | The desired block number for task execution. Must be in the future but within a reasonable window (MAX_SCHEDULE_DISTANCE ). |
maxPayment | uint256 | Maximum payment (in MON equivalent) the scheduler is willing to offer for execution. Influences executor incentives. msg.value must cover the calculated executionCost . |
taskCallData | bytes | The encoded function call data intended for the implementation contract (will be passed through the task proxy via delegatecall ). |
Name | Type | Description |
---|
scheduled | bool | Whether the task was successfully scheduled. |
executionCost | uint256 | The estimated cost (required MON payment in msg.value ) for the task. |
taskId | bytes32 | Unique identifier (keccak256 ) for tracking the scheduled task. |
async function scheduleTaskWithMON(
implementation,
targetBlock,
taskCallData
) {
const taskGasLimit = 100_000n;
const estimatedCost = await taskManager.estimateCost(targetBlock, taskGasLimit);
const maxPayment = estimatedCost;
const tx = await taskManager.scheduleTask(
implementation,
taskGasLimit,
targetBlock,
maxPayment,
taskCallData,
{ value: estimatedCost }
);
const receipt = await tx.wait();
}
scheduleWithBond
function scheduleWithBond(
address implementation,
uint256 taskGasLimit,
uint64 targetBlock,
uint256 maxPayment,
bytes calldata taskCallData
) external returns (bool scheduled, uint256 executionCost, bytes32 taskId);
Schedules a task for execution at a future targetBlock
, paying the execution cost using the caller's bonded shMONAD. This function is not payable
.
- The
implementation
address is the contract containing the task logic. The Task Manager deploys a task-specific proxy (mimic) which will delegatecall
this implementation
.
- Requires the caller to have sufficient bonded
shMONAD
(under the Task Manager's POLICY_ID
) to cover the returned executionCost
. The contract will attempt to transfer the required bond amount.
- Parameters
- Return Values
- Usage Example
Name | Type | Description |
---|
implementation | address | The contract address containing the task logic. A task-specific proxy deployed by the Task Manager will delegatecall this contract's code during execution. |
taskGasLimit | uint256 | The gas limit allocated for the task's execution logic within the implementation . Determines the task size category (Small, Medium, Large). |
targetBlock | uint64 | The desired block number for task execution. Must be in the future but within a reasonable window (MAX_SCHEDULE_DISTANCE ). |
maxPayment | uint256 | Maximum payment (in MON equivalent) the scheduler is willing to offer for execution. Influences executor incentives. Required bond must cover the calculated executionCost . |
taskCallData | bytes | The encoded function call data intended for the implementation contract (will be passed through the task proxy via delegatecall ). |
Name | Type | Description |
---|
scheduled | bool | Whether the task was successfully scheduled. |
executionCost | uint256 | The estimated cost (required bonded shMONAD) for the task. |
taskId | bytes32 | Unique identifier (keccak256 ) for tracking the scheduled task. |
async function scheduleTaskWithBond(
implementation,
targetBlock,
taskCallData
) {
const taskGasLimit = 100_000n;
const estimatedCost = await taskManager.estimateCost(targetBlock, taskGasLimit);
const maxPayment = estimatedCost;
const tx = await taskManager.scheduleWithBond(
implementation,
taskGasLimit,
targetBlock,
maxPayment,
taskCallData
);
const receipt = await tx.wait();
}
executeTasks
function executeTasks(
address payoutAddress,
uint256 targetGasReserve
) external returns (uint256 feesEarned);
Executes queued tasks up to the target gas reserve. This function is typically called by automated Executors who scan for pending tasks and perform their execution to earn fees.
- Parameters
- Return Values
- Usage Example
Name | Type | Description |
---|
payoutAddress | address | The beneficiary address that will receive the fees earned from executing tasks. Can be the caller or any other valid address. |
targetGasReserve | uint256 | Amount of gas to reserve after execution. The executor should provide a value ensuring sufficient gas for the function to complete safely. |
Name | Type | Description |
---|
feesEarned | uint256 | Total amount of fees earned in native MON from task execution. |
async function executeTasksAsBatch(payoutAddress) {
const targetGasReserve = 100_000n;
const tx = await taskManager.executeTasks(
payoutAddress,
targetGasReserve
);
const receipt = await tx.wait();
console.log(`Executed tasks and earned ${receipt.events[0].args.feesEarned} MON`);
}
rescheduleTask
function rescheduleTask(
uint64 targetBlock,
uint256 maxPayment
) external payable returns (bool rescheduled, uint256 executionCost, bytes32 taskId);
Intended to be called by the task-specific proxy/mimic address (environment
) during task execution. Allows a task's logic (running via delegatecall
from the proxy) to reschedule itself for a future block.
- Parameters
- Return Values
- Important Notes
- Usage Example
Name | Type | Description |
---|
targetBlock | uint64 | The desired future block number for the rescheduled task execution. Must be in the future but within a reasonable window (MAX_SCHEDULE_DISTANCE ). |
maxPayment | uint256 | Maximum payment (in MON equivalent) the scheduler is willing to offer for execution. Influences executor incentives. Either msg.value or bonded shMONAD must cover the executionCost . |
Name | Type | Description |
---|
rescheduled | bool | Whether the task was successfully rescheduled. |
executionCost | uint256 | The estimated cost for the rescheduled task. |
taskId | bytes32 | Unique identifier (keccak256 ) for tracking the rescheduled task. |
- Can only be called successfully from the
environment
address associated with the taskId
currently being executed (tracked in transient storage T_currentTaskId
).
- The original
taskId
is marked internally, and a new task is scheduled with the same implementation
and taskCallData
but updated targetBlock
and maxPayment
.
- Requires sufficient payment (either via
msg.value
sent by the environment
during the call, or using remaining bonded shMONAD
associated with the original task owner) to cover the executionCost
of the rescheduled task.
- For recurring tasks, this function must be used with bonded shMONAD (not with direct MON payments), as contracts typically can't hold or transfer native MON. See Recurring Tasks documentation for more details.
function executeTask(bytes calldata taskData) external returns (bool) {
uint64 nextBlock = uint64(block.number) + 100;
uint256 maxPayment = 0.01 ether;
(bool rescheduled, , bytes32 newTaskId) = ITaskManager(TASK_MANAGER).rescheduleTask(
nextBlock,
maxPayment
);
require(rescheduled, "Failed to reschedule task");
return true;
}
cancelTask
function cancelTask(bytes32 taskId) external;
Cancels a scheduled task. This prevents the task from being executed and releases any associated bonds or payments.
- Parameters
- Important Notes
- Usage Example
Name | Type | Description |
---|
taskId | bytes32 | The identifier of the task to cancel. |
- Can only be called by the task owner or an address explicitly authorized via
addTaskCanceller
or addEnvironmentCanceller
.
- A successfully cancelled task cannot be executed or rescheduled.
- Cancellation releases any associated bonds back to the task owner.
async function cancelScheduledTask(taskId) {
const tx = await taskManager.cancelTask(taskId);
await tx.wait();
const isCancelled = await taskManager.isTaskCancelled(taskId);
console.log(`Task ${taskId} cancelled: ${isCancelled}`);
}
Task Status Queries
function isTaskCancelled(bytes32 taskId) external view returns (bool cancelled);
function isTaskExecuted(bytes32 taskId) external view returns (bool executed);
These functions check the status of a task:
- Parameters
- Return Values
- Usage Example
Name | Type | Description |
---|
taskId | bytes32 | The identifier of the task to query. |
Name | Type | Description |
---|
cancelled | bool | Whether the task has been cancelled (for isTaskCancelled). |
executed | bool | Whether the task has been executed (for isTaskExecuted). |
async function checkTaskStatus(taskId) {
const isCancelled = await taskManager.isTaskCancelled(taskId);
const isExecuted = await taskManager.isTaskExecuted(taskId);
if (isCancelled) {
console.log(`Task ${taskId} has been cancelled`);
} else if (isExecuted) {
console.log(`Task ${taskId} has been executed successfully`);
} else {
console.log(`Task ${taskId} is still pending execution`);
}
}
estimateCost
function estimateCost(
uint64 targetBlock,
uint256 taskGasLimit
) external view returns (uint256 cost);
Estimates the cost (in MON or equivalent bonded shMONAD) required to schedule a task.
- Parameters
- Return Values
- Usage Example
Name | Type | Description |
---|
targetBlock | uint64 | The block number for which to estimate execution costs. Congested blocks may have higher execution costs. |
taskGasLimit | uint256 | The gas limit for task execution. Determines the task size category (Small, Medium, Large). |
Name | Type | Description |
---|
cost | uint256 | The estimated cost in native MON (or equivalent bonded shMONAD) required for the task. |
async function estimateTaskExecutionCost(taskGasLimit) {
const currentBlock = await provider.getBlockNumber();
const targetBlock = currentBlock + 10;
const cost = await taskManager.estimateCost(targetBlock, taskGasLimit);
console.log(`Estimated cost for task execution: ${ethers.formatEther(cost)} MON`);
return cost;
}
function getTaskMetadata(
bytes32 taskId
) external view returns (TaskMetadata memory);
Retrieves metadata associated with a specific task. The metadata (owner
, nonce
, size
) is stored keyed by the task's unique environment (proxy/mimic) address, which is derived from the taskId
.
- Parameters
- Return Values
- Usage Example
Name | Type | Description |
---|
taskId | bytes32 | The identifier of the task to query. The environment address is derived from this ID. |
Name | Type | Description |
---|
- | TaskMetadata | A struct containing metadata about the task (owner, size, nonce, etc.). |
async function getTaskDetails(taskId) {
const metadata = await taskManager.getTaskMetadata(taskId);
console.log(`Task Owner: ${metadata.owner}`);
console.log(`Task Size: ${metadata.size}`);
console.log(`Task Nonce: ${metadata.nonce}`);
}
getNextExecutionBlockInRange
function getNextExecutionBlockInRange(
uint64 startBlock,
uint64 endBlock
) external view returns (uint64);
Finds the earliest block with scheduled tasks in the specified range.
- Parameters
- Return Values
- Usage Example
Name | Type | Description |
---|
startBlock | uint64 | Start of the block range (inclusive). |
endBlock | uint64 | End of the block range (inclusive). |
Type | Description |
---|
uint64 | The earliest block number with tasks scheduled, or 0 if none found in range. |
async function findNextExecutionBlock() {
const currentBlock = await provider.getBlockNumber();
const startBlock = currentBlock;
const endBlock = currentBlock + 100;
const nextBlock = await taskManager.getNextExecutionBlockInRange(startBlock, endBlock);
if (nextBlock !== 0) {
console.log(`Next block with scheduled tasks: ${nextBlock}`);
return nextBlock;
} else {
console.log(`No scheduled tasks found in the next 100 blocks`);
return null;
}
}
Authorization Management
Task-Specific Authorization
function addTaskCanceller(bytes32 taskId, address canceller) external;
function removeTaskCanceller(bytes32 taskId, address canceller) external;
Manage addresses authorized to cancel specific tasks.
- Parameters
- Important Notes
- Usage Example
Name | Type | Description |
---|
taskId | bytes32 | The identifier of the task for which to add/remove cancellation rights. |
canceller | address | The address to grant or revoke cancellation rights. |
- Can only be called by the task owner or an authorized manager.
- Allowed cancellers can call
cancelTask
for the specific task ID.
- The task owner always retains cancellation rights regardless of these settings.
async function grantCancellationPermission(taskId, cancellerAddress) {
const tx = await taskManager.addTaskCanceller(taskId, cancellerAddress);
await tx.wait();
console.log(`Address ${cancellerAddress} can now cancel task ${taskId}`);
}
Environment-Wide Authorization
function addEnvironmentCanceller(bytes32 taskId, address canceller) external;
function removeEnvironmentCanceller(bytes32 taskId, address canceller) external;
Manage addresses authorized to cancel all tasks for an environment.
- Parameters
- Important Notes
- Usage Example
Name | Type | Description |
---|
taskId | bytes32 | A task identifier used to determine the environment. All tasks using this environment will be affected. |
canceller | address | The address to grant or revoke environment-wide cancellation rights. |
- Can only be called by the task owner or an authorized manager.
- Allowed environment cancellers can call
cancelTask
for any task using the same environment.
- The
taskId
parameter is used to verify ownership and identify the environment.
- This provides a way to grant broader cancellation rights across multiple related tasks.
async function grantEnvironmentCancellationPermission(taskId, cancellerAddress) {
const tx = await taskManager.addEnvironmentCanceller(taskId, cancellerAddress);
await tx.wait();
console.log(`Address ${cancellerAddress} can now cancel all tasks in the environment`);
}
See Also