Job (Old)

The Job is a smart contract to be automated that is registered in The Agent.

Overview

To automate their smart contract execution, a user registers it in The Agent, and the Job is created.

The Job consists of the smart contract and the binary information, stored inside The Agent.

There may be three types of the Jobs:

  • Selector

    Selector-type job is the basic task that requires execution of a certain function in the smart contract based on some conditions, for example, periodically. To register this Job, the provider specifies the selector of the function to be called during execution.

  • Predefined calldata

    A slightly more complex Job. Alongside with the selector, the provider supplies via the function setJobPredefinedCalldata the byte array of predefined calldata that must be passed to the function during execution. The above function is only invoked manually when a job is switched to have this type; for jobs that are registered as ones with predefined calldata, the calldata is simply passed in the corresponding argument. For example, a vault reward harvest with option of automatic restake will be such a task: the harvest function is called with a boolean (True or False) argument to either restake or collect the reward.

  • Resolver

    The most complex type of Job. Resolver is the function in a smart contract that defines the conditions of the target function execution (may be the same address, though likely not also selector, as the Job). The Resolver contains the logic to define if the Job should be executed and returns the calldata to pass to the job function for execution. The Resolver is configured by the Job provider themselves.

โ‹…โ‹…โ‹…\cdot \cdot \cdot

Specification

Structure

The Job inside the Agent is represented as a data structure struct Job containing the following fields:

Binary layout

To achieve efficiency and save on gas during execution, all manipulations with the Job structure are performed in assembly inserts. The binary representation of struct Job is as follows:

Since in RanDAO realisation the fixed reward actually corresponds to a portion of the executor keeper/slasher's stake and not a pre-defined job parameter, for RanDAO jobs the fixedReward field retains its position and size, but now corresponds to the value _jobMaxCvpStake, which is the upper bound on the size of stake for the purposes of computing rewards. The purpose of this value is the prevention of disproportionately excessive payouts should the keeper have too great a stake.

Job config

The Job configuration is a single byte inside the Job structure and defines the properties of the Job. The bits are allocated consecutively in the uint8 config.

  • CFG_ACTIVE

    Flag of a job being active (i.e., admissible for execution given satisfaction of specified logic).

  • CFG_USE_JOB_OWNER_CREDITS

    Whether to use job owner credits in native tokens for payment. This makes a hard switch from using job credits to using job owner credits and not just enables it as an option.

  • CFG_ASSERT_RESOLVER_SELECTOR

    Indicates whether to enforce the selector of a resolver job function matching between the calldata passed by the Keeper and the job binary representation. This may be desirable because under the hood, resolver jobs work like PRE_DEFINED jobs, except the calldata is provided by the Keeper. It would therefore be possible for a malicious Keeper to supply a different selector, which is not checkable unless this flag is set to True. Has no bearing on interval jobs, since for them, the calldata is fixed.

  • CFG_CHECK_KEEPER_MIN_CVP_DEPOSIT

    Whether to enforce conformance of the stake of keepers and slashers to the minimum required stake of the job.

Resolver & Calldata

Resolver is a method in a contract (may be a separate resolver contract or the same contract as the Job) that is called by the Keeper before execution (with some calldata (resolverCalldata), may be empty) and returns a flag (whether or not the target method of the Job should be executed) and the calldata (executionCalldata) necessary for the execution.

Drawing
Execution diagram for resolver jobs

The execution calldata layout is presented below:

Data parameters description

The last field (executionCalldata) has to do with the calldata with which to call the underlying function consists of a function selector (in the contract at jobContractAddress) for SELECTOR-type jobs, predefined calldata for PRE_DEFINED-type jobs, and whatever calldata is returned by the resolver for RESOLVER-type jobs. Mind that the RESOLVER-returned calldata must obey the ABI specification, including the demand for the first four bytes to be the selector of the called function.

Mappings

A list of mappings in the Agent contract which are related to the Job structure (bytes32 indicates the key is the jobKey, a value obtained by taking keccak256 hash of a concatenation of a Job's address and ID, in that order):

RanDAO-specific mappings

Functions

registerJob

Registers a new Job.

In RanDAO realisation, the timsetamp at which the job was created is stored in the mapping jobCreatedAt. The reason for this is elucidated in RanDAO-specific mappings.

updateJob

Updates the job parameters to the provided values.

setJobResolver

Sets the job resolver parameters

setJobPredefinedCalldata

Sets the job predefined calldata (for jobs of corresp type)

setJobConfig

Sets the job config flags to the specified values.

RanDAO realisation peculiarities

Since in RanDAO realisation executor keepers are assigned beforehand, we need to handle possible assignment and release at every job parameter update, since otherwise we may have a keeper with an inactive job assigned or an active job that does not get a keeper assigned for some time.

The inputs of the function stay much the same, but the internal logic changes. We supply the annotated code:

Logic for assignment and release can be found in Keeper assignment and release in RanDAO realisation.

initiateJobTransfer

Initiates transfer of job ownership to a specified address; must be finalized by the recipient calling the following function.

acceptJobTransfer

Finalises previously initialised job ownership transfer.

depositJobCredits

Replenishes the amount of native chain tokens the job has for disbursement to keepers as a reward.

This function is payable; the depositor calls the function and specifies the amount of native token to deposit (i.e., Ether) within the value field of the message

withdrawJobCredits

Withdraws native tokens from a jobโ€™s credit total to a specified address.

To withdraw all credits, specify amount_ as type(uint256).max.

depositJobOwnerCredits

Deposits native chain tokens to the job ownerโ€™s balance, which may be used by this owner to pay for execution of any of his jobs, provided the appropriate flag in the job config is set to True.

This function is payable; the depositor calls the function and specifies the amount of native token to deposit (i.e., Ether) within the value field of the message

withdrawJobOwnerCredits

Withdraws native tokens from the job ownerโ€™s balance to a specified address.

To withdraw all credits, specify amount_ as type(uint256).max.

assignKeeper

Manually assigns a keeper to each job of a certain list (unless one is already extant).

releaseJob

Manually releases a keeper from executing a job.

Last updated

Was this helpful?