Skip to Content

AutomationRegistry

The automation registry lets a contract be called on a schedule without anyone sending a transaction. A user registers a task describing a call to make and a condition gating it, pays a fee up front, and the chain schedules that call for execution in every committed block of a running cycle until the task ends. A task ends by expiring, by being cancelled or stopped, by the runtime removing it, by the owner’s balance or allowance falling short of a cycle fee, by its fee cap falling below the cycle fee, or by the registry being suspended. System tasks pay no fee. See How Automation Works.

Registration eligibility, fees and capacity are governed by automation cycles, which are independent of block production. See How Automation Works for the cycle and fee model behind this page’s reference material.

Each execution appears on chain as an automated transaction, which is visible over RPC alongside ordinary transactions — see Automated Transactions over RPC.

The registry is an EIP-2535 diamond. Its functionality is split across seven facets, but every call goes to the single diamond address.

Finding it

Read the address under the contract registry key AutomationRegistry — the contract registry being the 0x1::evm_config::EvmContractsDetails resource, not this registry.

The examples on this page use these shell variables. RPC is a JSON-RPC endpoint, not a host. The values here are Devnet’s; its contract addresses are also listed in Addresses on Devnet:

RPC=https://rpc-devnet.supra.com/rpc/v1/eth/wallet_integration WSUPRA=0x6a042b8a99cdd407669ce5d124416007f323afdd AUTOMATION_REGISTRY=0xa75a2cd8e61992526ed2eeaf1e1ab3b9ec472400 USER="<address of the task owner>"

PAYLOAD_TX and PREDICATE are the encodings built under Encoding the call, as 0x-prefixed hex. EXPIRY_TIME and GAS_PRICE_CAP are the task’s _expiryTime and _gasPriceCap, set as the table under Registering describes. FEE_CAP, CYCLES and TOTAL_FEE are set under Paying.

Before using it, check that it is both initialized and switched on:

cast call "$AUTOMATION_REGISTRY" "isAutomationReadyEnabled()(bool)" --rpc-url "$RPC"

A chain configured without automation parameters has no automation registry at all, and the AutomationRegistry key is absent from the contract registry.

On a newly created chain, no automation cycle ends until monitorCycleEnd() has been registered in BlockMeta. Genesis does not register it; a foundation-wallet action does afterwards. Until then the cycle stays STARTED past its end time and every registered task stays PENDING. Genesis also sets the automation flag from the chain’s automation parameters, so check isAutomationEnabled() as well — registration reverts with AutomationNotEnabled while it is off.

Calling a diamond

Send every call to the diamond address. Its fallback looks the function selector up in its own storage and delegates to the facet that implements it. The facets are separate contracts, but they hold no state and are not meant to be called directly; a call sent to a facet address operates on that facet’s own empty storage.

The diamond’s fallback is not payable, so the registry cannot receive native SUPRA. Fees are paid in WSUPRA, the token of the WrappedSupra contract — contract registry key WrappedSupra — documented in Predeployed Contracts. The automation registry returns that contract’s address from erc20Supra().

Which facet serves a selector is discoverable at runtime:

cast call "$AUTOMATION_REGISTRY" "facets()((address,bytes4[])[])" --rpc-url "$RPC" cast call "$AUTOMATION_REGISTRY" "facetAddress(bytes4)(address)" 0xdda12a93 --rpc-url "$RPC"

A selector that is not registered reverts with FunctionDoesNotExist.

supportsInterface reports IERC165, IDiamondCut, IDiamondLoupe, IERC173 and IRegistryStatus. These ids are registered once when the diamond is initialized and are not reconciled when a later diamondCut adds or removes functions, so a true result means the interface was registered at genesis rather than that every one of its functions is currently routed. Use the loupe to determine what is actually callable.

IFacetSelectors.getSelectors() is implemented by the facets but is not registered on the diamond, so it can only be called on a facet address directly.

Registering a task

Encoding the call

The task’s action is ABI-encoded into _payloadTx:

bytes memory payloadTx = abi.encode( uint128(value), // native value to send with the call address(target), // contract to call bytes(abi.encodeCall(ITarget.doWork, ())), // calldata new LibCommon.AccessListEntry[](0) // access list, may be empty );

Every task also carries a predicate, checked before each execution; the action runs only when the predicate returns true:

bytes memory predicate = abi.encode( address(predicateTarget), bytes(abi.encodeCall(IPredicate.isReady, ())) );

With Foundry, for a TARGET contract whose doWork() is the action and whose isReady() is the predicate:

PAYLOAD_TX=$(cast abi-encode "f(uint128,address,bytes,(address,bytes32[])[])" \ 0 "$TARGET" "$(cast calldata "doWork()")" "[]") PREDICATE=$(cast abi-encode "f(address,bytes)" "$TARGET" "$(cast calldata "isReady()")")

The Solidity blocks on this page omit their import lines and the declarations of the types they name, such as ITarget, IPredicate and LibCommon.

A predicate is mandatory. An empty _predicate passes the size and length checks, then fails to decode as (address, bytes), and registration reverts with no named error.

At execution, the action and the predicate are transactions sent by the task owner, so msg.sender, tx.origin and the transaction sender are the owner, and nonce is the task index. At registration the predicate is called by the registry, so msg.sender inside it is the registry. A predicate that reverts, halts or attempts a state change at execution removes the task; an action that reverts, halts or is discarded leaves it registered, and a user task’s action pays gas from the owner’s native balance. See What an execution looks like.

Both values must be whole ABI encodings: their lengths must be multiples of 32 bytes, or registration reverts with PayloadNotWordAligned or PredicateNotWordAligned. Output of abi.encode always satisfies this; a hand-built value with trailing bytes does not.

The predicate is staticcalled at registration time to validate it, under the task’s _maxGasAmount, and must return a single 32-byte value that is 0 or 1. See How Automation Works for what happens when it reverts or returns false at execution time.

Paying

Registration charges flatRegistrationFeeWei + _automationFeeCapForCycle in WSUPRA, taken with transferFrom. The flat fee is a registry setting, so read it from getConfig() rather than assuming a value. It is the fourth field of the returned Config struct, after registryMaxGasCap, sysRegistryMaxGasCap and automationBaseFeeWeiPerSec. Estimate the per-cycle component before choosing _automationFeeCapForCycle, which is FEE_CAP in the registration command below:

# The flat fee, in wei: the fourth value of getConfig(). FLAT_FEE=$(cast call "$AUTOMATION_REGISTRY" "getConfig()(uint128,uint128,uint128,uint128)" \ --rpc-url "$RPC" | sed -n 4p | cut -d' ' -f1) # The per-cycle fee for a task with a gas ceiling of 500000, in wei. ESTIMATE=$(cast call "$AUTOMATION_REGISTRY" "estimateAutomationFee(uint128)(uint128)" 500000 \ --rpc-url "$RPC" | cut -d' ' -f1)

Choose FEE_CAP at or above the estimate. _automationFeeCapForCycle is held as the task’s deposit; it does not pay for a cycle. Each cycle’s fee is charged separately, by transferFrom from the owner’s WSUPRA balance and allowance at the boundary that starts the cycle, the first cycle included, and is at most FEE_CAP. If either the balance or the allowance is below the fee, the task is removed with TaskCancelledInsufficientBalanceAllowance and the registry keeps the deposit. Wrap and approve the flat fee, the deposit and CYCLES cycle fees, with CYCLES the number of cycles the task should run. ./k is a keystore file made with cast wallet import k --keystore-dir . --interactive, which prompts for the private key and a password:

FEE_CAP=$ESTIMATE CYCLES=2 TOTAL_FEE=$((FLAT_FEE + FEE_CAP + CYCLES * FEE_CAP)) # Wrap native SUPRA into WSUPRA, then approve the registry for the total fee. cast send "$WSUPRA" "deposit()" --value "$TOTAL_FEE" --keystore ./k --rpc-url "$RPC" cast send "$WSUPRA" "approve(address,uint256)" "$AUTOMATION_REGISTRY" "$TOTAL_FEE" \ --keystore ./k --rpc-url "$RPC"

A task that runs for more than CYCLES cycles needs its balance and its allowance raised before the boundary that starts each further cycle.

The fee rises with how much of the cycle’s gas capacity is already committed, so an estimate taken now can be too low by the time the next cycle starts. The cap is the maximum the task will pay per cycle; a task whose cap falls below the cycle’s actual fee is cancelled rather than executed, and emits TaskCancelledCapacitySurpassed.

Two further bounds come from the chain’s EVM gas config rather than the registry: _maxGasAmount may not exceed the per-transaction gas cap, and a user task’s _gasPriceCap may not be below the minimum gas price. Both are checked at registration and again whenever the gas config changes; see Gas and Fees.

Registering

The task runs with its owner as the transaction sender, and a sender with code (other than an EIP-7702 delegation) is refused. A task registered by a contract is removed at its first predicate evaluation, so call register from an account without code.

EXPIRY_TIME below is the end of the last cycle that CYCLES covers, and GAS_PRICE_CAP is in wei:

CYCLE_INFO=$(cast call "$AUTOMATION_REGISTRY" "getCycleInfo()(uint64,uint64,uint64,uint8)" \ --rpc-url "$RPC") CYCLE_START=$(echo "$CYCLE_INFO" | sed -n 2p | cut -d' ' -f1) CYCLE_DURATION=$(echo "$CYCLE_INFO" | sed -n 3p | cut -d' ' -f1) EXPIRY_TIME=$((CYCLE_START + (CYCLES + 1) * CYCLE_DURATION)) GAS_PRICE_CAP=1000000000000
cast send "$AUTOMATION_REGISTRY" \ "register(bytes,bytes,uint64,uint128,uint128,uint128,uint64,bytes[])" \ "$PAYLOAD_TX" "$PREDICATE" "$EXPIRY_TIME" 500000 "$GAS_PRICE_CAP" "$FEE_CAP" 0 "[]" \ --keystore ./k --rpc-url "$RPC"
ParameterMeaning
_payloadTxThe encoded action, as above
_predicateThe encoded predicate. Required
_expiryTimeAbsolute timestamp after which the task stops running
_maxGasAmountGas ceiling for one execution, shared by the predicate and the action, each transaction’s intrinsic gas included. At most the chain’s per-transaction gas cap
_gasPriceCapHighest gas price the task will pay. At least the chain’s minimum gas price
_automationFeeCapForCycleMaximum fee the task will pay per cycle
_priorityIgnored for a user task, whose priority is always its task index. Only registerSystemTask honours a nonzero value
_auxDataAuxiliary data. Capped at zero entries at genesis, so pass an empty array

_expiryTime must be later than the end of the registration cycle; otherwise, registration reverts with TaskExpiresBeforeNextCycle.

Reading tasks back

TASK_INDEX is an index returned by getTasksByAddress.

cast call "$AUTOMATION_REGISTRY" "getTasksByAddress(address)(uint256[])" "$USER" --rpc-url "$RPC" cast call "$AUTOMATION_REGISTRY" "getTaskDetails(uint64)" "$TASK_INDEX" --rpc-url "$RPC" cast call "$AUTOMATION_REGISTRY" "getActiveTaskIds()(uint64[])" --rpc-url "$RPC"

Over JSON-RPC without Foundry:

curl -X POST "$RPC" -H 'Content-Type: application/json' -d '{ "jsonrpc": "2.0", "id": 1, "method": "eth_call", "params": [{ "to": "'"$AUTOMATION_REGISTRY"'", "data": "0x2321cca3" }, "latest"] }'

Stopping a task

FunctionEffect
cancelTasks(uint64[])Cancels tasks owned by the caller. A PENDING task is removed immediately; an ACTIVE task becomes CANCELLED and keeps executing until the current cycle ends
stopTasks(uint64[])Stops tasks owned by the caller, removing them immediately whatever their state, and refunds

To halt an active task at once, stop it rather than cancel it; see Cancelling versus stopping.

The refund depends on both which function is called and the task’s current state — a PENDING task refunds only half its deposit on either path, while an ACTIVE task refunds in full and, through stopTasks, also refunds half the residual cycle fee. See How Automation Works for the complete table.

Task indexes that do not exist are skipped rather than causing a revert, so a batch containing a stale index still processes the rest.

TaskMetadata

getTaskDetails and getTaskDetailsBulk return:

FieldTypeMeaning
maxGasAmountuint128Gas ceiling for one execution
gasPriceCapuint128Highest gas price the task will pay
automationFeeCapForCycleuint128Maximum fee per cycle
depositFeeuint128Deposit currently locked
txHashbytes32Hash of the registration transaction
taskIndexuint64The task’s identifier
registrationTimeuint64When it was registered
expiryTimeuint64When it stops running
priorityuint64Ordering hint. Always the task index for UST; a supplied nonzero value for GST
owneraddressWho may cancel or stop it
taskTypeTaskTypeUST or GST
taskStateTaskStatePENDING, ACTIVE or CANCELLED
payloadTxbytesThe encoded action
predicatebytesThe encoded predicate
auxDatabytes[]Auxiliary data

Enum values as they appear on the wire:

CycleStateTaskStateTaskTypeTaskRemovalReason
0READY0PENDING0UST (user-submitted)0ERROR
1STARTED1ACTIVE1GST (governance-submitted, gasless)1GAS_CONFIG_UPDATE
2FINISHED2CANCELLED
3SUSPENDED

Registration is only accepted while the cycle state is STARTED. While automation is enabled, a call during a transition reverts with CycleTransitionInProgress; while it is disabled, the error is AutomationNotEnabled.

Who can call what

Anyone

FunctionEffect
register(...)Registers a user task. Requires a WSUPRA approval. A task registered by a caller with code cannot run
All get*, if*, has*, total*, is*, estimate* and calculate* functionsReads
facets, facetAddresses, facetFunctionSelectors, facetAddress, supportsInterface, isInitializedDiamond introspection

Task owners

FunctionEffect
cancelTasks(uint64[]), stopTasks(uint64[])On UST tasks the caller owns
cancelSystemTasks(uint64[]), stopSystemTasks(uint64[])On GST tasks the caller owns

When the caller owns the task, calling the UST variant on a GST task, or the reverse, reverts with UnsupportedTaskOperation. A caller that does not own the task reverts with UnauthorizedAccount.

Authorized submitters

FunctionEffect
registerSystemTask(...)Registers a GST task. No fee is charged

System tasks are a governance mechanism for protocol upkeep, not a service users apply for. A system task also runs with its owner as the transaction sender, so a system task registered by a contract, including a multisig authorized submitter, is removed at its first predicate evaluation; register it from an account without code. The authorized set is managed by the owner through grantAuthorization and revokeAuthorization. Check membership with isAuthorizedSubmitter(address).

Owner

The owner is the foundation wallet, so each of these requires a multisig proposal.

FunctionEffect
enableAutomation(), disableAutomation()Enables automation, or disables it, which suspends the registry and removes and refunds every task
enableRegistration(), disableRegistration()Turns new registrations on or off
grantAuthorization(address), revokeAuthorization(address)Changes the authorized submitter set
updateConfigBuffer(...)Stages a configuration change, applied at the next cycle boundary
updateDataLengthCaps(...)Changes payload, predicate and auxiliary-data size caps, effective immediately. The payload and predicate caps must be multiples of 32
withdrawFees(uint256,address)Withdraws collected fees, bounded by the locked balance
diamondCut(...)Adds, replaces or removes facet functions
transferOwnership(address)One-step. Renouncing is not supported

updateConfigBuffer is buffered rather than immediate, so a configuration change is adopted at the next cycle boundary. The exceptions are nextCycleRegistryMaxGasCap and nextCycleSysRegistryMaxGasCap, which take effect immediately and change what registration accepts. Read the staged values with getConfigBuffer() and the active ones with getConfig().

VM signer

These are driven by block production and cannot be called by any account, because no transaction can be sent from a reserved address. They are listed so they can be recognised in traces and in RPC responses.

FunctionEffect
monitorCycleEnd()Checks whether the cycle has ended. Called each block through BlockMeta once it is registered there, which happens after genesis
processTasks(uint64,uint64[])Bookkeeping applied at a cycle transition — activates and charges tasks, does not execute a task’s payload
removeRegisteredTask(uint64,uint64,uint8,string)Removes a task, giving a TaskRemovalReason and a details string: ERROR for a task the runtime found invalid, GAS_CONFIG_UPDATE for one a new EVM gas config no longer admits

monitorCycleEnd() checks tx.origin rather than msg.sender, because it is reached through BlockMeta.blockPrologue() and so its immediate caller is BlockMeta.

When calls fail

Registration, which has the largest set of preconditions:

ErrorCondition
AutomationNotEnabled()Automation is switched off
RegistrationDisabled()Registration is switched off
CycleTransitionInProgress()Automation is enabled and the cycle is not in STARTED
PayloadTooLarge()_payloadTx exceeds maxPayloadLength
PayloadNotWordAligned()_payloadTx’s length is not a multiple of 32
InvalidPayloadLength()The decoded call data is under 4 bytes — checked separately for the action payload inside _payloadTx and for the predicate’s payload inside _predicate
AddressCannotBeZero(), AddressCannotBeEOA()The payload or predicate target is zero or has no code
InvalidMaxGasAmount()_maxGasAmount is zero
MaxGasAmountExceedsChainCap(uint128,uint64)_maxGasAmount exceeds the chain’s per-transaction gas cap. Applies to user and system tasks, and is checked before the predicate is called
PredicateTooLarge()_predicate exceeds maxPredicateLength
PredicateNotWordAligned()_predicate’s length is not a multiple of 32
— (no named error)_predicate is empty bytes. It passes the two checks above, then fails to decode as (address, bytes)
StaticCallToPredicateFailed()The predicate reverted when validated
InvalidReturnLengthOfPredicate()The predicate returned other than 32 bytes
InvalidReturnTypeOfPredicate()The predicate returned a value other than 0 or 1
TaskCapacityReached()The number of registered tasks of that type, in any state, has reached taskCapacity (sysTaskCapacity for a system task)
InvalidGasPriceCap()_gasPriceCap is zero
GasPriceCapBelowMinimum(uint128,uint256)A user task’s _gasPriceCap is below the chain’s minimum gas price. System tasks are exempt
InsufficientFeeCapForCycle(uint128)_automationFeeCapForCycle is below the current cycle fee. The payload is the required amount
InvalidExpiryTime()_expiryTime is in the past
InvalidTaskDuration()The lifetime exceeds the configured duration cap
TaskExpiresBeforeNextCycle()_expiryTime is not later than the end of the registration cycle, so the task would expire before it could ever run
GasCommittedExceedsMaxGasCap()The gas committed for the next cycle would exceed nextCycleRegistryMaxGasCap (nextCycleSysRegistryMaxGasCap for a system task)
AuxDataTooLarge()_auxData exceeds the configured caps
TransferFailed()The WSUPRA token returned false from transferFrom
UnauthorizedAccount()registerSystemTask from an address that is not an authorized submitter

A missing WSUPRA approval or balance reverts with the token’s own error, ERC20InsufficientAllowance(address,uint256,uint256) or ERC20InsufficientBalance, which register forwards.

Cancelling and stopping:

ErrorCondition
TaskIndexesCannotBeEmpty()An empty array was passed
UnauthorizedAccount()The caller does not own the task
UnsupportedTaskOperation()The owner used the UST variant on a GST task, or the reverse
AlreadyCancelled()The task is already cancelled (cancelTasks and cancelSystemTasks only; the stop functions accept a cancelled task)
AutomationNotEnabled()Automation is switched off
CycleTransitionInProgress()The cycle is mid-transition

Configuration and ownership:

ErrorCondition
MustBeContractOwner()An owner-gated function called by another account
AlreadyEnabled(), AlreadyDisabled()A toggle set to its current value
AddressAlreadyExists(), AddressDoesNotExist()Granting or revoking authorization redundantly
InsufficientBalance(), RequestExceedsLockedBalance()withdrawFees beyond the unlocked balance
UnacceptableRegistryMaxGasCap(), UnacceptableSysRegistryMaxGasCap()A staged gas cap below what is already committed
PayloadLengthCapNotWordAligned(), PredicateLengthCapNotWordAligned()updateDataLengthCaps with a payload or predicate cap that is not a multiple of 32
FunctionDoesNotExist()The selector is not routed by the diamond

Events

EventEmitted whenIndexed
TaskRegistered(uint64,address,uint128,uint128,TaskMetadata)A user task is registeredtaskIndex, owner
SystemTaskRegistered(uint64,address,uint256,TaskMetadata)A system task is registeredtaskIndex, owner
TasksCancelled(TaskCancelled[],address)Tasks are cancelledowner
TasksStopped(TaskStopped[],address)Tasks are stoppedowner
TaskFeeRefund(uint64,address,uint128)A cycle fee is refundedtaskIndex, owner
TaskDepositFeeRefund(uint64,address,uint128)A deposit is refundedtaskIndex, owner
AutomationCycleEvent(uint64,CycleState,uint64,uint64,CycleState)A cycle changes stateindex, state, oldState
ActiveTasks(uint64,uint64[])A cycle starts with tasks active in it, listing them; not emitted for a cycle with nonecycleIndex
RemovedTasks(uint64,CycleState,uint64[])Tasks are dropped at a cycle transition (state FINISHED) or on suspension (SUSPENDED)cycleIndex, state
TaskCycleFeeWithdraw(uint64,uint64,address,uint128)A task’s cycle fee is taken. cycleIndex is the cycle the fee pays forcycleIndex, taskIndex, owner
TaskCancelledCapacitySurpassed(uint64,address,uint128,uint128,bytes32)A task’s fee cap was below the cycle feetaskIndex, owner
TaskCancelledInsufficientBalanceAllowance(uint64,address,uint128,uint256,uint256,bytes32)A task’s owner lacked balance or allowancetaskIndex, owner
TaskRemovedBySystem(uint64,address,TaskType,bytes32,TaskRemovalReason,string)The runtime removed an invalid tasktaskIndex, owner
TaskRemovedByGasConfigUpdate(uint64,address,TaskType,uint128,uint128,uint64,uint256,uint128,uint128,bytes32)A new EVM gas config no longer admits a tasktaskIndex, owner, taskType
ErrorUnlockTaskCycleFee, ErrorUnlockTaskDepositFee, ErrorInsufficientBalanceToRefundA refund could not be paid in full; diagnostictaskIndex, and on the last also owner and refundType
AutomationEnabled(bool), AutomationDisabled(bool)Automation toggledstatus
TaskRegistrationEnabled(bool), TaskRegistrationDisabled(bool)Registration toggledstatus
AuthorizationGranted(address,uint256), AuthorizationRevoked(address,uint256)Authorized set changedaccount, timestamp
RegistryFeeWithdrawn(address,uint256)Fees withdrawnrecipient
ConfigBufferUpdated(Config)Configuration stagednone
DataLengthCapsUpdated(uint16,uint16,uint16,uint16)Size caps changednone
DiamondCut(FacetCut[],address,bytes)Facet functions changednone
OwnershipTransferred(address,address)Ownership changedpreviousOwner, newOwner

No registry event indexes a struct, array, string, bytes value or amount. Those parameters are ABI-encoded in the log data, so taskMetadata, the cancelled and stopped task lists, the task-index arrays and every fee and refund amount decode directly from the log. Filter by the indexed task index, owner or cycle, and read the rest from the data.

Four events tell a task owner why a task stopped running: TaskCancelledCapacitySurpassed when the fee cap was too low for the cycle, TaskCancelledInsufficientBalanceAllowance when the owner’s WSUPRA balance or allowance was insufficient at charging time, TaskRemovedBySystem when the runtime rejected the task, and TaskRemovedByGasConfigUpdate when a new EVM gas config no longer admits it.

Interfaces

Selector map

FacetSelectors
DiamondCutFacetdiamondCut
DiamondLoupeFacetfacets, facetFunctionSelectors, facetAddresses, facetAddress, supportsInterface, isInitialized
OwnershipFacetowner, transferOwnership
ConfigFacetgrantAuthorization, revokeAuthorization, enableRegistration, disableRegistration, withdrawFees, updateConfigBuffer, updateDataLengthCaps, erc20Supra, isRegistrationEnabled, getConfig, getConfigBuffer, getDataLengthCaps
CoreFacetprocessTasks, monitorCycleEnd, removeRegisteredTask, enableAutomation, disableAutomation, getCycleInfo, getCycleDuration, getTransitionInfo, isAutomationEnabled, getCycleStateDetails, isAutomationReadyEnabled
RegistryFacetregister, registerSystemTask, cancelTasks, cancelSystemTasks, stopTasks, stopSystemTasks, isAuthorizedSubmitter, calculateAutomationFeeMultiplierForCommittedOccupancy, calculateAutomationFeeMultiplierForCurrentCycle, estimateAutomationFee, estimateAutomationFeeWithCommittedOccupancy
RegistryViewFacetgetTaskIdList, getSystemTaskIds, getTaskOwner, getNextTaskIndex, totalTasks, totalSystemTasks, getTaskDetails, getTaskDetailsBulk, getTotalActiveTasks, getActiveTaskIds, hasActiveUserTask, hasActiveSystemTask, hasActiveTaskOfType, getGasCommittedForNextCycle, getGasCommittedForCurrentCycle, getSystemGasCommittedForNextCycle, getSystemGasCommittedForCurrentCycle, getNextCycleRegistryMaxGasCap, getNextCycleSysRegistryMaxGasCap, getCycleLockedFees, getTotalDepositedAutomationFees, getTotalLockedBalance, ifTaskExists, ifSysTaskExists, getTasksByAddress

The live mapping is whatever the loupe reports; this table describes the genesis wiring.

Signatures and selectors

SignatureSelectorMutability
register(bytes,bytes,uint64,uint128,uint128,uint128,uint64,bytes[])0xdda12a93nonpayable
registerSystemTask(bytes,bytes,uint64,uint128,uint64,bytes[])0x45147fe4nonpayable
cancelTasks(uint64[])0x71d35334nonpayable
stopTasks(uint64[])0xaf783c6dnonpayable
getTaskDetails(uint64)0xb2ef6896view
getTaskIdList()0xec82b429view
getActiveTaskIds()0x2321cca3view
getTasksByAddress(address)0xe6ef3231view
getTaskOwner(uint64)0xb36b5fe9view
ifTaskExists(uint64)0x8aaa404eview
estimateAutomationFee(uint128)0xf8b6f14fview
isAuthorizedSubmitter(address)0x09479e8cview
getCycleInfo()0x873dc71dview
getCycleStateDetails()0x6b5d8c56view
isAutomationEnabled()0xe48e0e98view
isAutomationReadyEnabled()0x105176ceview
isInitialized()0x392e53cdview
getConfig()0xc3f909d4view
getDataLengthCaps()0xd55df358view
isRegistrationEnabled()0x1fdfe815view
owner()0x8da5cb5bview
facets()0x7a0ed627view
facetAddress(bytes4)0xcdffacc6view
facetAddresses()0x52ef6b2cview
facetFunctionSelectors(address)0xadfca15eview
supportsInterface(bytes4)0x01ffc9a7view
diamondCut((address,uint8,bytes4[])[],address,bytes)0x1f931c1cnonpayable
monitorCycleEnd()0x1b87619cnonpayable
processTasks(uint64,uint64[])0x7f69c35cnonpayable
removeRegisteredTask(uint64,uint64,uint8,string)0x256e4e4dnonpayable

Solidity

The interfaces are IRegistryFacet.sol, IRegistryViewFacet.sol, ICoreFacet.sol, IConfigFacet.sol, IDiamondCut.sol, IDiamondLoupe.sol, IERC173.sol, IERC165.sol and IRegistryStatus.sol. The task-owner surface follows. The blocks omit the imports of the published files: TaskMetadata is declared in LibAppStorage.sol and LibCommon in LibCommon.sol, both in the registry’s libraries directory.

interface IRegistryFacet { function register( bytes memory _payloadTx, bytes memory _predicate, uint64 _expiryTime, uint128 _maxGasAmount, uint128 _gasPriceCap, uint128 _automationFeeCapForCycle, uint64 _priority, bytes[] memory _auxData ) external; function cancelTasks(uint64[] memory _taskIndexes) external; function stopTasks(uint64[] memory _taskIndexes) external; function estimateAutomationFee(uint128 _taskOccupancy) external view returns (uint128); } interface IRegistryViewFacet { function getTaskDetails(uint64 _taskIndex) external view returns (TaskMetadata memory); function getTaskDetailsBulk(uint64[] memory _taskIndexes) external view returns (TaskMetadata[] memory); function getTasksByAddress(address _addr) external view returns (uint256[] memory); function getActiveTaskIds() external view returns (uint64[] memory); function getTaskOwner(uint64 _taskIndex) external view returns (address); function ifTaskExists(uint64 _taskIndex) external view returns (bool); }
interface ICoreFacet { event AutomationCycleEvent( uint64 indexed index, LibCommon.CycleState indexed state, uint64 startTime, uint64 durationSecs, LibCommon.CycleState indexed oldState ); function getCycleInfo() external view returns (uint64, uint64, uint64, LibCommon.CycleState); function getCycleDuration() external view returns (uint64); function getCycleStateDetails() external view returns (LibCommon.CycleDetails memory); function isAutomationEnabled() external view returns (bool); function isAutomationReadyEnabled() external view returns (bool); }

JSON ABI

A diamond has no single compiled ABI, because its surface is the union of its facets. Generate each facet interface’s ABI from the solidity/supra_contracts directory, as described in Interfaces and ABIs, and concatenate them into one an EVM client can bind to the diamond address:

for i in IRegistryFacet IRegistryViewFacet ICoreFacet IConfigFacet IDiamondLoupe IDiamondCut; do forge inspect "$i" abi --json > "$i.json" done jq -s 'add' IRegistryFacet.json IRegistryViewFacet.json ICoreFacet.json IConfigFacet.json \ IDiamondLoupe.json IDiamondCut.json > AutomationRegistry.json

The fragment for registering a task:

[ { "type": "function", "name": "register", "inputs": [ { "name": "_payloadTx", "type": "bytes" }, { "name": "_predicate", "type": "bytes" }, { "name": "_expiryTime", "type": "uint64" }, { "name": "_maxGasAmount", "type": "uint128" }, { "name": "_gasPriceCap", "type": "uint128" }, { "name": "_automationFeeCapForCycle", "type": "uint128" }, { "name": "_priority", "type": "uint64" }, { "name": "_auxData", "type": "bytes[]" } ], "outputs": [], "stateMutability": "nonpayable" } ]
Last updated on