# Job

## Overview

To automate their smart contract execution, a user must submit the task into the PowerAgent network. It is done via an intuitive UI in the PowerAgent dApp. The guide on how to submit your task is located [here](https://docs.powerpool.finance/powerpool-and-poweragent-network/power-agent/user-guides-and-instructions/i-want-to-automate-my-tasks).

The Job is basically comprised of two parts:

* The **target** smart **contract**, complemented perhaps with a resolver smart contract (see [Resolver Jobs](#resolver) below) and
* The **binary information** about the execution properties (stored inside The Agent).

***

## Job types

There may be two types of the Jobs: Interval-based and Resolver-based.

### **Interval**

Interval-based job is the basic task that requires execution of a certain function in the smart contract periodically. To register this Job, you only provide the selector of the function to be called during execution and the execution interval.

{% hint style="success" %}
For example, if there exists a helper contract which has a function of harvesting rewards from a vault necessarily with restake, such a job will be a **Selector** job; no parameter enters the target function, since it is fixed via the helper wrapper.
{% endhint %}

#### **Predefined calldata**

Alongside with the selector, you may set predefined calldata that must be passed to the function during execution.&#x20;

{% hint style="success" %}
If the reward harvest function is parameterized and invoked directly, this job will instead be a **Predefined Calldata** job: the harvest function is called with a boolean (`True` or `False`) argument to either restake or collect the reward.
{% endhint %}

### **Resolver**

This job execution scenario is based on arbitrary logic rather than on time intervals.

A resolver is a function that defines the conditions of the target function execution. A resolver contains the logic to define if the job should be executed and returns the calldata to pass to the job function for execution. You have to configure and deploy the resolver before submitting your task for automation.

{% hint style="success" %}
Finally, if you want that to harvest rewards only when a certain amount of them i accrued, and possibly their restaking is also dependent on some on-chain conditions, such a job will be a **Resolver** job, which relies upon on-chain logic (in the simplest case, a comparison of the accrued amount with a threshold value).
{% endhint %}

***

## Short Specification

The Agent stores the job as a formatted binary string (see the full specification for the details). This binary string corresponds to essentially a nested struct with the following fields:

```json
{
    "targetAddress": address, //the target address
    "id": uint256, //the number of this job among all jobs with the same target address
    "key": bytes32, //unique identifier; equals keccak256(targetAddress[96:]||id[232:])
    
    "config": {
        "isActive": bool, //job activity flag
        "usesJobOwnerCredits": bool, //whether to pay with job or job owner balance
        "assertResolverSelector": bool, //assert that the returned calldata matches the provided selector
        "checkAssignedKeeperMinCvpDeposit": bool //check that the keeper has no less than a job-specific amount staked
    },

    "selector": bytes4, //selector of the target method; valid only for Selector type
    "credits": uint88, //the job's balance for payment
    "maxBaseFeeGwei": uint16, // a cap on the block’s base gas fee for the purposes of computing rewards
    "rewardPct": uint16, //unused in the current implementation
    "fixedReward": uint32, //a cap on the keeper stake for the purposes of computing rewards
    "jobMinCvp": uint256, //the minimal stake the executor must possess
    "calldataSource": uint8, //enum of calldata sources; [SELECTOR, PREDEF_CDATA, RESOLVER]
    "intervalSeconds": uint24, //interval size in seconds; only for interval jobs
    "lastExecutionAt": uint32, // last execution timestamp; only for interval jobs
    "predefinedCalldata": bytes, //predefined calldata bytestring, for the appropriate source
    "resolverAddress": address, //resolver contract address for resolver jobs
    "resolverCalldata": bytes //calldata to pass to the resolver contract (for resolver jobs)
}
```

During registration, the user only provides the following data:

* `calldataSource`
* `targetAddress`
* `intervalSeconds`
* `resolverAddress`
* `resolverCalldata`
* `predefinedCalldata`
* `selector`
* `jobMinCvp`
* `credits`
* `config`

{% hint style="info" %}
When registering a job via UI, most of the fields are implicitly set to default values (for instance, `usesJobOwnerCredits` and `assertResolverSelector` are automatically set to `true`).
{% endhint %}
