# Introduction

*These docs are in active development by the Keep3r community.*

The Keep3r Network is a decentralized network for projects that need external devops, and for external teams to find keeper jobs.

## [Keepers](/core/keepers)

A Keeper is the term used to refer to an external address that executes a job. This can be as simplistic as calling a transaction, or as complex as requiring extensive off-chain logic. The scope of Keep3r network is not to manage these jobs themselves, but to allow contracts to register as jobs for keepers, and keepers to register themselves as available to perform jobs. It is up to the individual keeper to set up their DevOps and infrastructure and create their own rules based on what transactions they deem profitable.

## [Jobs](/core/jobs)

A Job is the term used to refer to a smart contract that wishes an external entity to perform an action. They would like the action to be performed in "good will" and not have a malicious result. For this reason they register as a job, and keepers can then execute on their contract. Both relying on the Keep3r ecosystem to mediate in the event of a dispute.

## [Credits](/tokenomics/job-payment-mechanisms)

Credits are used to pay keepers for their work. A job can either top up your credits [with tokens](/tokenomics/job-payment-mechanisms/token-payments), or by mining credits with time by [staking liquidity](/tokenomics/job-payment-mechanisms/credit-mining).


# Jobs

## Quick Start Examples

### Simple Keeper

To setup a keeper function simply add the following modifier in your contract:

```
modifier validateAndPayKeeper(address _keeper) {
  if (!IKeep3r(keep3r).isKeeper(_keeper)) revert KeeperNotValid();
  _;
  IKeep3r(keep3r).worked(_keeper);
}
```

It could be then implement it like this:

```
function work() external validateAndPayKeeper(msg.sender) {
  // ...
}
```

The above will make sure the caller is a registered keeper as well as reward them with an amount of KP3R equal to their gas spent + premium. Make sure to have enough credits assigned in the Keep3r system for the relevant job.

## Adding Jobs

Jobs can be created directly via [`addJob()`](https://github.com/keep3r-network/keep3r-network-v2/blob/main/solidity/contracts/peripherals/jobs/Keep3rJobManager.sol).

```
  /// @notice Allows any caller to add a new job
  /// @param _job Address of the contract for which work should be performed
  function addJob(address _job) external;
```

## Managing Credits

Jobs need credit to be able to pay keepers, this credit can either be paid for directly (see [Token Payments](/tokenomics/job-payment-mechanisms/token-payments)), or by being a liquidity provider (see [Credit Mining](/tokenomics/job-payment-mechanisms/credit-mining)) in the system. If you pay directly, this is a direct expense, if you are a liquidity provider, you get all your liquidity back after you are done being a provider.

### Start mining credits for your job via Liquidity

To start mining credits, you will need to provide [LP tokens](/tokenomics/keep3r-liquidity-pools) as liquidity by calling [`addLiquidityToJob()`](https://github.com/keep3r-network/keep3r-network-v2/blob/main/solidity/interfaces/peripherals/IKeep3rJobs.sol). You receive all your LP tokens back when you no longer need to provide credit for a contract.

```
  /// @notice Allows anyone to fund a job with liquidity
  /// @param _job The address of the job to assign liquidity to
  /// @param _liquidity The liquidity being added
  /// @param _amount The amount of liquidity tokens to add
  function addLiquidityToJob(
    address _job,
    address _liquidity,
    uint256 _amount
  ) external;
```

### Remove liquidity from a job

To remove your liquidity from a job, you will need to call [`unbondLiquidityFromJob()`](https://github.com/keep3r-network/keep3r-network-v2/blob/main/solidity/interfaces/peripherals/IKeep3rJobs.sol).

```
  /// @notice Unbond liquidity for a job
  /// @dev Can only be called by the job's owner
  /// @param _job The address of the job being unbound from
  /// @param _liquidity The liquidity being unbound
  /// @param _amount The amount of liquidity being removed
  function unbondLiquidityFromJob(
    address _job,
    address _liquidity,
    uint256 _amount
  ) external;
```

Wait `UNBOND` (default 14 days) days and call [`withdrawLiquidityFromJob()`](https://github.com/keep3r-network/keep3r-network-v2/blob/main/solidity/interfaces/peripherals/IKeep3rJobs.sol).

```
  /// @notice Withdraw liquidity from a job
  /// @param _job The address of the job being withdrawn from
  /// @param _liquidity The liquidity being withdrawn
  /// @param _receiver The address that will receive the withdrawn liquidity
  function withdrawLiquidityFromJob(
    address _job,
    address _liquidity,
    address _receiver
  ) external;
```

### Adding credits directly (non ETH)

To add Token Credits to your job, you will need to call [`addTokenCreditsToJob()`](https://github.com/keep3r-network/keep3r-network-v2/blob/main/solidity/interfaces/peripherals/IKeep3rJobs.sol).&#x20;

{% hint style="info" %}
Adding KP3R tokens is not allowed this way, the only way is via liquidity mining.
{% endhint %}

```
  /// @notice Add credit to a job to be paid out for work
  /// @param _job The address of the job being credited
  /// @param _token The address of the token being credited
  /// @param _amount The amount of credit being added
  function addTokenCreditsToJob(
    address _job,
    address _token,
    uint256 _amount
  ) external;
```

## Selecting Keepers

Dependent on your requirements you might allow any keepers, or you want to limit specific keepers, you can filter keepers based on `age`, `bond`, `total earned funds`, or even arbitrary values such as additional bonded tokens.

### No access control

Accept all keepers in the system.

```
/// @notice Confirms if the current keeper is registered, can be used for general (non critical) functions
/// @param _keeper The keeper being investigated
/// @return _isKeeper Whether the address passed as a parameter is a keeper or not
function isKeeper(address _keeper) external returns (bool _isKeeper);
```

### Filtered access control

Filter keepers based on bonded amount of tokens, earned funds, and age in system. For example a keeper might need to have `SNX` to be able to participate in the [Synthetix](https://synthetix.io/) ecosystem.

```
/// @notice Confirms if the current keeper is registered and has a minimum bond of any asset. Should be used for protected functions
/// @param _keeper The keeper to check
/// @param _bond The bond token being evaluated
/// @param _minBond The minimum amount of bonded tokens
/// @param _earned The minimum funds earned in the keepers lifetime
/// @param _age The minimum keeper age required
/// @return _isBondedKeeper Whether the `_keeper` meets the given requirements
function isBondedKeeper(
  address _keeper,
  address _bond,
  uint256 _minBond,
  uint256 _earned,
  uint256 _age
) external returns (bool _isBondedKeeper);
```

## Paying Keepers

There are two primary payment mechanisms and these are based on the credit provided;

* Pay via liquidity provided tokens (based on `addLiquidityToJob`)
* Pay in direct token (based on `addTokenCreditsToJob`)

## Auto Pay

### Pay for Work

If you don't want to worry about calculating payment, you can simply let the system calculate the recommended payment itself.

```
/// @notice Implemented by jobs to show that a keeper performed work
/// @dev Automatically calculates the payment for the keeper
/// @param _keeper Address of the keeper that performed the work
function worked(address _keeper) external;
```

### Pay with KP3R

```
/// @notice Implemented by jobs to show that a keeper performed work
/// @dev Pays the keeper that performs the work with KP3R
/// @param _keeper Address of the keeper that performed the work
/// @param _payment The reward that should be allocated for the job
function bondedPayment(address _keeper, uint256 _payment) external;
```

### Pay with an ERC20 token

```
/// @notice Implemented by jobs to show that a keeper performed work
/// @dev Pays the keeper that performs the work with a specific token
/// @param _token The asset being awarded to the keeper
/// @param _keeper Address of the keeper that performed the work
/// @param _amount The reward that should be allocated
function directTokenPayment(
  address _token,
  address _keeper,
  uint256 _amount
) external;
```

## Disputing and Slashing a Job

### **Disputed Job**

A job might be disputed by a [disputer](https://docs.thekeep3r.network/roles/disputer) if there is suspicious activity detected within that job.

A good behavior is expected from jobs, this includes but isn't limited to:

* NOT leverage the network of keepers for malicious activities (exploits, rug pulls, etc.).
* NOT limiting qualified keepers to work on their job.
* NOT creating a malicious workable function to drain credits from the network.

In case it's disputed, the job won't be able to be worked by keepers, withdraw LPs / tokens credits nor perform a job migration.

### **Slashed Jobs**

Jobs that are detected to have a malicious behavior within the network (either towards the network or the protocol they are working for — eg: exploiting a protocol) will get their LP tokens slashed and seized by governance.

## Job Migration

There may be situations where a job needs to migrate all of their "assets" to another contract address, for a job update for example. A proper migration implies the accountancy (tokens, liquidities, period credits) from the original job address will be transferred to the new one. This process is possible, and it requires the job to call two functions:

* [`migrateJob()`](https://github.com/keep3r-network/keep3r-network-v2/blob/main/solidity/interfaces/peripherals/IKeep3rJobs.sol)first to start the migration process. This function should be call by the owner of the job that currently holds the assets to migrate.

```
/// @notice Initializes the migration process for a job by adding the request to the pendingJobMigrations mapping
/// @param _fromJob The address of the job that is requesting to migrate
/// @param _toJob The address at which the job is requesting to migrate
function migrateJob(address _fromJob, address _toJob) external;
```

* [`acceptJobMigration()`](https://github.com/keep3r-network/keep3r-network-v2/blob/main/solidity/interfaces/peripherals/IKeep3rJobs.sol) to complete the migration process. This function should be call by the owner of the job that will receive the assets to migrate.

```
/// @notice Completes the migration process for a job
/// @dev Unbond/withdraw process doesn't get migrated
/// @param _fromJob The address of the job that requested to migrate
/// @param _toJob The address to which the job wants to migrate to
function acceptJobMigration(address _fromJob, address _toJob) external;
```

There are some considerations the job wishing to migrate must take into account to prevent the functions from reverting:

* It must not provide its current address as the address where it wants to migrate to when calling `migrateJob`.
* Calls to both `migrateJob` and `acceptJobMigration` should be done with the same arguments.&#x20;
* Neither of the jobs involved in the migration process should be disputed
* It must wait at least one minute between migrations

Here's a graphic representation to visualize the resulting changes in the credits of a job that goes through a successful migration.

![](/files/-MlASRNNgj62VQfYxumb)

## Additional Information

Once you set up your job on the protocol, you will be able to request for it to be registered on the Job Board providing the following data to governance:

* Job Address
* Job Name
* Job Address Link (Etherscan)
* Job Documentation (script)

This information will be used to display the job on the UI, and will provide users and keepers of the network with additional information regarding the jobs of the network.


# Keepers

Keepers are bots, scripts, other contracts, or simply EOA accounts that trigger events. This can be submitting a signed TX on behalf of a third party, calling a transaction at a specific time, or a more complex functionality.

Each time you execute such a function, you are rewarded in either tokens, or the systems native token KP3R.

Jobs might require keepers that have a minimum amount of bonded tokens, have earned a minimum amount of fees, or have been in the system longer than a certain period of time.

At the most simple level, they simply require a keeper to be registered in the system.

## Becoming a Keeper

To become a keeper, you simply need to call `bond(address,uint)`, no funds are required to become a keeper, however certain jobs might require a minimum amount of funds.

```
/// @notice Beginning of the bonding process
/// @param _bonding The asset being bound
/// @param _amount The amount of bonding asset being bound
function bond(address _bonding, uint256 _amount) external;
```

After waiting `bondTime` (default 3 days) and you can activate as a keeper;

```
/// @notice End of the bonding process after bonding time has passed
/// @param _bonding The asset being activated as bond collateral
function activate(address _bonding) external;
```

## Removing a Keeper

If you want to withdraw your bonds, you will need first to unbond them,

```
/// @notice Beginning of the unbonding process
/// @param _bonding The asset being unbound
/// @param _amount Allows for partial unbonding
function unbond(address _bonding, uint256 _amount) external;
```

{% hint style="info" %}
After a keeper has unbonded an asset amount, it may stop qualifying for the Filtered Access Control jobs, should they require to have bondings of that asset
{% endhint %}

After waiting `unbondTime` (default 14 days) you can withdraw any bonded assets

```
/// @notice Withdraw funds after unbonding has finished
/// @param _bonding The asset to withdraw from the bonding pool
function withdraw(address _bonding) external;
```

## **Disputing and Slashing a Keeper**

### **Disputed Keeper**

A Keeper might be disputed by a [disputer](https://docs.thekeep3r.network/roles/disputer) if there is suspicious activity detected within that keeper.

A good behavior is expected from keepers, this includes but isn't limited to:

* NOT working a malicious job
* NOT sandwiching a job

In case it's disputed, the keeper won't be able to bond or activate new assets nor withdraw its unbonded assets

### **Slashed Keeper**

Keepers that are detected to have a malicious behavior within the network (either towards the network or the protocol they are working for — eg: sandwiching a job) will get their bonded assets slashed and seized by governance

## Additional Requirements

Some jobs might have additional requirements such as minimum bonded protocol tokens (for example SNX). In such cases you would need to bond a minimum amount of SNX before you may qualify for the job.


# Governance

Keep3r Governance by design has a low overhead, it is not meant to be protocol intensive.

The tasks governance has are:

* Managing slashers and disputers
* Managing protocol parameters
* Managing approved liquidities
* Force-minting credits to a job

The focus of governance, however, is mainly put on reviewing jobs, and if absolutely required in mitigating disputes or blacklisting keepers.

## Managing Slashers

When keepers or jobs act in bad faith, measures must be taken to keep the network pruned of ill-intended actors. To ensure this, governance has the ability to add slashers, which are whitelisted addresses with special permissions over keepers and jobs.

Adding a slasher.

```
/// @notice Registers a slasher by updating the slashers mapping
function addSlasher(address _slasher) external;
```

Governance also has the ability to remove slashers.

```
/// @notice Removes a slasher by updating the slashers mapping
function removeSlasher(address _slasher) external;
```

> Governance itself can approve its own address to be a slasher

## Managing Disputers

When a keeper or a job is detected behaving strangely, actions must be taken to pause and study whether their behaviour is harmful to the network or not. To ensure these cases are frozen and inspected, governance has the ability to add disputers, which are whitelisted addresses with the ability to dispute jobs and keepers, forbidding them to exercise common actions like work a job or have a keeper work its job. A dispute also signals the slashers that there's a potential bad actor in the network, and the slasher will decide what measures to take.

Adding a disputer.

```
/// @notice Registers a disputer by updating the disputers mapping
function addDisputer(address _disputer) external;
```

Removing a disputer.

```
/// @notice Removes a disputer by updating the disputers mapping
function removeDisputer(address _disputer) external;
```

> Governance itself can approve its own address to be a disputer

## Managing Protocol Parameters

There are certain protocol-specific parameters that can be changed by governance to ensure the correct functioning of the network. These parameters range from bonding time to the addresses of contracts that interact with Keep3rV2.

### **Bond time**

```
/// @notice Sets the bond time required to activate as a keeper
/// @param _bond The new bond time
function setBondTime(uint256 _bond) external;
```

### **Unbond Time**

```
/// @notice Sets the unbond time required unbond what has been bonded
/// @param _unbond The new unbond time
function setUnbondTime(uint256 _unbond) external;
```

### **Minimum Liquidity**

```
/// @notice Sets the minimum amount of liquidity required to fund a job
/// @param _liquidityMinimum The new minimum amount of liquidity
function setLiquidityMinimum(uint256 _liquidityMinimum) external;
```

### **Reward Period Time**

```
/// @notice Sets the time required to pass between rewards for jobs
/// @param _rewardPeriodTime The new amount of time required to pass between rewards
function setRewardPeriodTime(uint256 _rewardPeriodTime) external;
```

### **Inflation Period**

```
/// @notice Sets the new inflation period
/// @param _inflationPeriod The new inflation period
function setInflationPeriod(uint256 _inflationPeriod) external;
```

### **Fee**

```
/// @notice Sets the new fee
/// @param _fee The new fee
function setFee(uint256 _fee) external;
```

### **KP3R-WETH Pool Address**

```
/// @notice Sets the KP3R-WETH pool address
/// @param _kp3rWethPool The KP3R-WETH pool address
function setkp3rWethPool(address _kp3rWethPool) external;
```

### **Keep3rV1Proxy Address**

```
/// @notice Sets the Keep3rV1Proxy address
/// @param _keep3rV1Proxy The Keep3rV1Proxy address
function setKeep3rV1Proxy(address _keep3rV1Proxy) external;
```

### **Keep3rV1 Address**

```
/// @notice Sets the Keep3rV1 address
/// @param _keep3rV1 The Keep3rV1 address
function setKeep3rV1(address _keep3rV1) external;
```

### **Keep3rHelper Address**

```
/// @notice Sets the Keep3rHelper address
/// @param _keep3rHelper The Keep3rHelper address
function setKeep3rHelper(address _keep3rHelper) external;
```

## Manage Approved Liquidities

Governance is in charge of approving and removing what liquidity pairs are accepted in the network.

```
/// @notice Approve a liquidity pair for being accepted in future
/// @param _liquidity The address of the liquidity accepted
function approveLiquidity(address _liquidity) external;
```

```
/// @notice Revoke a liquidity pair from being accepted in future
/// @param _liquidity The liquidity no longer accepted
function revokeLiquidity(address _liquidity) external;
```

## Force Liquidity Credits

Governance can temporarily give liquidity credits to jobs. These liquidity credits will expire after the current [reward period](/tokenomics/job-payment-mechanisms/credit-mining#reward-periods) has ended.

```
/// @notice Gifts liquidity credits to the specified job
/// @param _job The address of the job being credited
/// @param _amount The amount of liquidity credits to gift
function forceLiquidityCreditsToJob(address _job, uint256 _amount) external;
```


# Slasher

Slashers are governance-approved addresses with permission to exercise last resort punishments over keepers and jobs that act in bad faith. These permissions allow slashers to:

* Slash bonded assets from keepers
* Slash tokens and liquidities from jobs
* Blacklist keepers altogether, effectively rendering them unable to keep participating in the network.

> For a keeper or a job to be subjected to a possible slashing or blacklist, they have first to have been disputed by either governance or a disputer.

## Slashing Keepers

Slash the bonded asset of a keeper.

```
/// @notice Allows governance to slash a keeper based on a dispute
/// @param _keeper The address being slashed
/// @param _bonded The asset being slashed
/// @param _amount The amount being slashed
function slash(
  address _keeper,
  address _bonded,
  uint256 _amount
) external;
```

## Slashing Jobs

Slash an array of tokens from a job.

```
/// @notice Allows governance or slasher to slash a job specific token
/// @param _job The address of the job from which the token will be slashed
/// @param _tokens An array containing the token addresses that will be slashed
/// @param _amounts An array containing the amounts of token that will be slashed for each token
function slashTokenFromJob(
  address _job,
  address[] memory _tokens,
  uint256[] memory _amounts
) external;
```

Slash an array of liquidities from a job.

```
/// @notice Allows governance or a slasher to slash liquidity from a job
/// @param _job The address being slashed
/// @param _liquidities An array containing the liquidity addresses that will be slashed
/// @param _amounts An array containing the amounts of liquidity that will be slashed for each liquidity
function slashLiquidityFromJob(
  address _job,
  address[] memory _liquidities,
  uint256[] memory _amounts
) external;
```

## Blacklisting Keepers

Blacklists a keeper from the network.

```
/// @notice Blacklists a keeper from participating in the network
/// @param _keeper The address being slashed
function revoke(address _keeper) external;
```


# Disputer

Disputers are governance-approved addresses with permission to dispute keepers or jobs that may have acted in bad faith. Once a dispute has started, a slasher will be in charge of evaluating what measures to take. In the meantime, the disputed address will be unable to:

* If the disputed address is a keeper, it won't be able to:&#x20;
  * Bond or activate new assets&#x20;
  * Withdraw its unbonded assets

{% hint style="info" %}
A disputed keeper can keep working jobs until is revoked
{% endhint %}

* If the disputed address is a job, it won't be able to:&#x20;
  * Have keepers work the job
  * Withdraw liquidity or token credits from the job
  * Perform a job migration (if any of the addresses is disputed)

Once the slasher has acted upon the disputed address—or decided against taking actions as a result of not considering the job or keeper to have acted in bad faith—either governance or a disputer will be able to resolve the dispute.

## Disputing Keepers or Jobs

Disputes a keeper or a job.

```
/// @notice Allows governance to create a dispute for a given keeper/job
/// @param _jobOrKeeper The address in dispute
function dispute(address _jobOrKeeper) external;
```

## Resolve a Dispute

Resolves a dispute.

```
/// @notice Allows governance to resolve a dispute on a keeper/job
/// @param _jobOrKeeper The address cleared
function resolve(address _jobOrKeeper) external;
```


# Keep3r Liquidity Pools

## Keep3r Liquidity Provider Tokens

Keep3r Liquidity Provider Tokens, known as`kLP,`are protocol-specific tokens minted to the users that provide liquidity to the network's liquidity pools, also known as pair managers. Jobs can bond `kLP,`which will periodically generate `KP3R` credits for them, which can be used as a form of payment for the keepers that work their job. This is further explained in [Credit Mining](https://app.gitbook.com/@wonderland-1/s/keep3r-v2/~/drafts/-MlAXHGpKjiGu925cyCz/tokenomics/credits/credit-mining).

To achieve this, Keep3rV2 has a factory in charge of creating wrapper contracts designed to  manage the underlying token pairs they wrap. These wrappers or pair managers conform the network's accepted liquidity pools. They provide all the necessary functions to enable the user to get `kLP` in return for their liquidity provision to the underlying token pair, as well as the burning of those `kLP` to recover the liquidity they had previously provided.

The pair manager contracts' name and symbol subscribe to the the following nomenclature:

* Name: `Keep3rLP - token0/token1`.  For example:  `Keep3rLP - KP3R/WETH`
* Symbol: `kLP - token0/token1`.  For example:  `kLP - KP3R/WETH`

## Providing Liquidity

To provide liquidity, users have to approve their chosen pair manager contract to spend their ERC20 tokens and call the pair manager contract's `mint` function. **This function will provide liquidity to the underlying token pair, calculate the corresponding `kLP`owed to the user according to the liquidity they provided, and mint them to whatever address the user has chosen to mint them to**.

To compensate the protocol, the fees generated by the liquidity provided to the underlying token pair will go to governance.

{% hint style="info" %}
**For example**, Alice decides she needs a keeper to work on her job, but at the same time she wants to periodically earn `KP3R`. After doing some research, Alice finds about`kLP`and looks for the pair managers of the Keep3r Network. \
Among them she finds the `kLP - KP3R/WETH`pair manager. She looks for the contract's address, and approves it to spend her `KP3R` and `WETH`. Once all approvals are signed, Alice calls the `mint` function of the`kLP - KP3R/WETH`contract. The contract, in turn, mints her `kLP`, which she can bond in her job to periodically earn`KP3R`. Or, should she have a change of heart, Alice can burn her `kLP`in order to recover the `KP3R` and `WETH`she had provided.
{% endhint %}

```
/// @notice Mints kLP tokens to an address according to the liquidity the msg.sender provides to the UniswapV3 pool
/// @dev Triggers UniV3PairManager#uniswapV3MintCallback
/// @param amount0Desired The amount of token0 we would like to provide
/// @param amount1Desired The amount of token1 we would like to provide
/// @param amount0Min The minimum amount of token0 we want to provide
/// @param amount1Min The minimum amount of token1 we want to provide
/// @param to The address to which the kLP tokens are going to be minted to
/// @return liquidity kLP tokens sent in exchange for the provision of tokens
function mint(
  uint256 amount0Desired,
  uint256 amount1Desired,
  uint256 amount0Min,
  uint256 amount1Min,
  address to
) external returns (uint128 liquidity);
```

## Burning Liquidity

Liquidity providers can choose to burn their `kLP` in order to collect the liquidity they had previously provided. To do this, they must call the `burn` function.

{% hint style="danger" %}
**Only an address that holds kLP can call the burn function, otherwise it will revert.**
{% endhint %}

```
/// @notice Burns the corresponding amount of kLP tokens from the msg.sender and withdraws the specified liquidity
//          in the entire range
/// @param liquidity The amount of liquidity to be burned
/// @param amount0Min The minimum amount of token0 we want to send to the recipient (to)
/// @param amount1Min The minimum amount of token1 we want to send to the recipient (to)
/// @param to The address that will receive the due fees
/// @return amount0 The calculated amount of token0 that will be sent to the recipient
/// @return amount1 The calculated amount of token1 that will be sent to the recipient
function burn(
  uint128 liquidity,
  uint256 amount0Min,
  uint256 amount1Min,
  address to
) external returns (uint256 amount0, uint256 amount1);
```

## Transfer kLP

If a user wishes to transfer his kLP to another address, the user can call the `transfer` function.

```
/// @notice Transfer kLP from the caller to another address
/// @param to The address that will receive the kLP
/// @param amount The amount of kLP to be sent
function transfer(address to, uint256 amount) external returns (bool)
```

## Approve User to Spend my kLP

If a user has deposited liquidity in a pair manager and wants to approve another address to spend her `kLP`, all the user has to do is call the pair manager's `approve` function.

```
/// @notice Approves another address to spend the caller's kLP
/// @param spender The address allowed to spend the caller's kLP
/// @param amount The amount of kLP the spender will be able to spend
function approve(address spender, uint256 amount) external returns (bool);
```

{% hint style="info" %}
To execute `addLiquidityToJob` the provider needs first to approve the spending for the Keep3r address
{% endhint %}

## Position

The pair manager contracts include a function that allows anyone to check the pair manager's position in the underlying token pair.

```
/// @notice Returns the pair manager's position in the corresponding UniswapV3 pool
/// @return liquidity The amount of liquidity provided to the UniswapV3 pool by the pair manager
/// @return feeGrowthInside0LastX128 The fee growth of token0 as of the last action on the individual position
/// @return feeGrowthInside1LastX128 The fee growth of token1 as of the last action on the individual position
/// @return tokensOwed0 The uncollected amount of token0 owed to the position as of the last computation
/// @return tokensOwed1 The uncollected amount of token1 owed to the position as of the last computation
function position()
  external
  view
  returns (
    uint128 liquidity,
    uint256 feeGrowthInside0LastX128,
    uint256 feeGrowthInside1LastX128,
    uint128 tokensOwed0,
    uint128 tokensOwed1
  );
```


# Job Payment Mechanisms

There are 2 ways for a Job Manager to pay keepers to upkeep their job:

* Credit Mining
* Token Payments

## [Credit Mining](/tokenomics/job-payment-mechanisms/credit-mining)

A Job can pay their keepers via credits obtained by Credit Mining.

The Credit Mining mechanism allows anyone to provide liquidity on a [Keep3r Liquidity Pool](/tokenomics/keep3r-liquidity-pools) (kLP) and stake their kLP tokens on the [Keep3rJobFundableLiquidity](/technical/peripherals/ikeep3rjobfundableliquidity) contract in order to start the mining of KP3R credits.

The credits mined can only be used to pay for job works within the network and can't be withdrawn.&#x20;

Similar to [Jobs](/core/jobs) & [Keepers](/core/keepers), the credits can be slashed and/or revoked via the Slasher or Governance.

## [Token Payments](/tokenomics/job-payment-mechanisms/token-payments)

A Job can pay their keepers via token payments.

The token payment mechanism allows anyone to deposit ERC20s and set a rate of which they want to perform the payouts for the upkeep of their jobs.

Job Managers can also add on [`directTokenPayment()`](/technical/peripherals/ikeep3rjobworkable) and [`worked()`](/technical/peripherals/ikeep3rjobworkable) functions on their jobs, in order for the protocol to auto-calculate their job payouts based on the amount of gas spent on the particular upkeep transaction.

Similar to [Jobs](/core/jobs) & [Keepers](/core/keepers), the credits can be slashed and/or revoked via the Slasher or Governance.


# Credit Mining

### Job Credits

A Job can generate new credits with time, by bonding Keep3r Liquidity Pool tokens `kLP` to it. Liquidities will be handled by the [Keep3r Liquidity Pools](/tokenomics/keep3r-liquidity-pools).

Once `kLPs` are added to a job with [`addLiquidityToJob`](https://github.com/keep3r-network/keep3r-network-v2/blob/956dad62b359a43ca047a8895d6e6a21aa24fddc/solidity/contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol#L178), the job starts immediately to mine new KP3R credits, that can be collectable only by the keepers, in reward for working the job. The credit mining system requires no further action from the `jobOwner`.

{% hint style="info" %}
KP3R Credits can only be rewarded within the protocol, requiring an unbonding period that gives time to disputers to detect keepers and jobs that act in bad faith
{% endhint %}

#### Reward Periods

To handle KP3R credits minting and quoting, **Keep3r introduces reward periods, in which KP3R quote remains stable for each pair, and gas-efficiently processed**. These quotes are used within the protocol to mint credits and reward keepers.

The underlying KP3R of the liquidity provided, should generate the same amount of KP3R every [`inflationPeriod`](https://github.com/keep3r-network/keep3r-network-v2/blob/956dad62b359a43ca047a8895d6e6a21aa24fddc/solidity/contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol#L333), thereby minting the proportional amount each [`rewardPeriod`](https://github.com/keep3r-network/keep3r-network-v2/blob/956dad62b359a43ca047a8895d6e6a21aa24fddc/solidity/contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol#L333) as KP3R credits for the job. These credits are only to be earned by keepers when working the job, and by the end of each `rewardPeriod`, unused credits older than previous `rewardPeriodStart` are meant to expire.

![Credit mining without work](/files/-Ml5Vo0Nf5CCdjB_GAn4)

When a new `rewardPeriod` starts, the first keeper to work the first job will:

* Perform the job action
* Reward the job or update its accountance
  * Update the quote of the KP3R/WETH pool
  * Update the quotes of each of the job liquidities

Following keepers of different jobs, will have to update each job accountance (when worked for the first time in the period), but won't have to update the quotes of KP3R/WETH and the liquidities the first job had, since they will be already updated.&#x20;

Updating jobs accountance requires no other action from the keeper than working the job.

{% hint style="info" %}
A `worked()` transaction that has to update quotes and reward the job is more gas-consuming, therefore has a higher keeper reward
{% endhint %}

#### Quoting the Liquidity

To determine the value of a certain liquidity, Keep3r uses a TWAP calculation to get the average quote of a pair in the last completed period. The same calculation is applied to quote rewards for keepers (that spend gas in ETH and receive KP3R rewards), using a predefined KP3R/WETH pool as an oracle.

* A job will mint the result of [`quoteLiquidity`](https://github.com/keep3r-network/keep3r-network-v2/blob/956dad62b359a43ca047a8895d6e6a21aa24fddc/solidity/contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol#L103) every `rewardPeriodTime`&#x20;
* `quoteLiquidity` will use the average quote for the last `epoch`for the given liquidity
* Remaining credits will be updated to current quotes each time a `rewardPeriod` starts

#### Job Credit accountance

At every time, a job will have its **current credits** (already rewarded and stored as `jobLiquidityCredits`) and **pending mined credits** to be rewarded (aggregated with current credits in `totalJobCredits`).&#x20;

A keeper will be able to run the job, as long as `totalJobCredits` is greater than the payment. If [`jobLiquidityCredits`](https://github.com/keep3r-network/keep3r-network-v2/blob/956dad62b359a43ca047a8895d6e6a21aa24fddc/solidity/contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol#L60) are not enough to pay the keeper, then the keeper will have to reward the job by rewarding the job with its mined credits.

In a normal case scenario, a job should be rewarded once every reward period starts, and burn all remaining credits from the expired period (the one previous to the last full period).&#x20;

![Normal case scenario](/files/-Ml5WHIsro6TzRYrq0BQ)

In a deficitary job scenario, when the job is spending more KP3R in a period than it should be rewarded, the job will be able to keep on paying keepers, but the minting period will start to shrink, having to mint more frequently.

![Deficitary job scenario](/files/-Ml5Wiza8Zbqzdf_1RK-)

Each time, the reward period will be shorter, as the job is not being rewarded the full amount for a period, but only the proportional relation of the time that passed since the last reward, and the `rewardPeriod`.

Ultimately, when the job has not enough `totalJobCredits` to reward the keeper for working the job (and some extra to pay the keeper for rewarding the credits), the transaction will revert with `InsufficientFunds`.

#### Credits maximum spending

At particular times, a job can make a payment of up to 2 times its [`jobPeriodCredits`](https://github.com/keep3r-network/keep3r-network-v2/blob/956dad62b359a43ca047a8895d6e6a21aa24fddc/solidity/contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol#L44), as long as all the credits minted have not yet expired.&#x20;

![Credits spending greater than jobPeriodCredits](/files/-Ml5Zr2u_SddGHaLAvGW)

**Updating Credits**

Since quotes can change every epoch, Keep3r recalculates every period how many KP3R a job should be mined each period, aggregated by [`jobPeriodCredits`](https://github.com/keep3r-network/keep3r-network-v2/blob/956dad62b359a43ca047a8895d6e6a21aa24fddc/solidity/contracts/peripherals/jobs/Keep3rJobFundableLiquidity.sol#L44).

![Credit mining with quote change](/files/-Ml5XygFjlY2FmEkf-3p)

Since KP3R/WETH is also stored and **stable inside periods**, keeper payments are also updated to current quotes.

![Work scenario with quote change](/files/-Ml5cGps99xlqzDKoBqs)

#### Removing Liquidity

At any time, the `jobOwner` can withdraw the liquidity bonded to the job, provided he either removes the total of it, or that he remains a minimum allowed amount.&#x20;

To withdraw a liquidity, first has to unbond the liquidity from the job with `unbondLiquidityFromJob`, instantly diminishing the job KP3R credits proportional to the impact of removing such liquidity. After an `unbondPeriod` passes, the `jobOwner` can withdraw the liquidity tokens from the protocol with `withdrawLiquidityFromJob`.


# Token Payments

Jobs as well can top-up their credits with ERC20 tokens, and then use them to reward keepers.

## Add Tokens To Job

Anyone can add token credits to a job by approving a transfer of an ERC20 token and then calling:

```
/// @notice Add credit to a job to be paid out for work
/// @param _job The address of the job being credited
/// @param _token The address of the token being credited
/// @param _amount The amount of credit being added
function addTokenCreditsToJob(
  address _job,
  address _token,
  uint256 _amount
) external;
```

This function will give the job token credits in a 1:1 relation to the transferred ERC20 tokens. Job token credit balance can be checked calling:

```
/// @notice The current token credits available for a job
/// @return _amount The amount of token credits available for a job
function jobTokenCredits(address _job, address _token) external view returns (uint256 _amount);
```

{% hint style="danger" %}
The only way of adding KP3R credits to a job is by [Credit Mining](/tokenomics/job-payment-mechanisms/credit-mining). Trying to add KP3R tokens by using `addTokenCreditsToJob` will revert.
{% endhint %}

## Withdraw Tokens From Job

A job owner can withdraw tokens credits from a job by calling:

```
/// @notice Withdraw credit from a job
/// @param _job The address of the job from which the credits are withdrawn
/// @param _token The address of the token being withdrawn
/// @param _amount The amount of token to be withdrawn
/// @param _receiver The user that will receive tokens
function withdrawTokenCreditsFromJob(
  address _job,
  address _token,
  uint256 _amount,
  address _receiver
) external;
```

This function can revert if:

* Job is disputed
* Token credits were added to the job at most 1 minute before trying to withdraw

## Pay Keepers With Token Credits

In order to reward keepers for their work with token credits jobs can call:

```
/// @notice Implemented by jobs to show that a keeper performed work
/// @dev Pays the keeper that performs the work with a specific token
/// @param _token The asset being awarded to the keeper
/// @param _keeper Address of the keeper that performed the work
/// @param _amount The reward that should be allocated
function directTokenPayment(
  address _token,
  address _keeper,
  uint256 _amount
) external;
```


# Overview

Keep3r-CLI provides an easy-to-use tool along with all the necessary code required to run your own keeper and start working on jobs. All you need to provide is your configuration file.

{% embed url="<https://twitter.com/DeFi_Wonderland/status/1448730195217813506?s=20>" %}

#### For Keepers

The easiest to become a keeper and start earning rewards for working jobs is by using the CLI. After cloning the CLI you will need to install CLI compatible jobs, add your configuration, and hit play! For more information you can read the complete [CLI Documentation](https://github.com/keep3r-network/cli/blob/master/README.md).

#### For Job Owners

If you are planning to add your job to the Keep3r Network, making it CLI compatible would be the quickest way to fully integrate it into the network. This will allow Keepers to install it and start working it in a minute or less. For more information you can read our [CLI Sample Jobs](https://github.com/keep3r-network/cli-sample-jobs/blob/master/README.md).


# Technical


# peripherals


# IKeep3rJobFundableLiquidity


# IKeep3rJobs


# IKeep3rJobOwnership


# IKeep3rKeeperFundable


# IKeep3rJobMigration


# IKeep3rJobManager


# IKeep3rKeeperDisputable


# IKeep3rJobWorkable


# IKeep3rParameters


# IGovernable


# IKeep3rKeepers


# IKeep3rRoles


# IKeep3rAccountance


# IKeep3rJobFundableCredits


# IKeep3rDisputable


# IKeep3rJobDisputable


# external


# IKeep3rV1Proxy


# IKeep3rGovernance


# IMasterChefV2


# IWeth9


# IKeep3rV1


# IKeep3rHelper


# IPairManager


# IPairFactory


# IUniV3PairManager


# IKeep3r


# Registry

## Beta Addresses

| Keep3r V2                      | 0xeb02addCfD8B773A5FFA6B9d1FE99c566f8c44CC |
| ------------------------------ | ------------------------------------------ |
| Keep3r Helper                  | 0xD36Ac9Ff5562abb541F51345f340FB650547a661 |
| KP3R \[ERC20]                  | 0x1ceb5cb57c4d4e2b2433641b95dd330a33185a44 |
| Pair Manager Factory \[Uni V3] | 0x053D7DD4dde2B5e4F6146476B95EA8c62cd7c428 |

## Pair Managers

| kLP KP3R/WETH | 0x3f6740b5898c5D3650ec6eAce9a649Ac791e44D7 |
| ------------- | ------------------------------------------ |

## Job Registry

Keep3rV2 Registry: <https://github.com/keep3r-network/job-registry/>

> To add a job to the Registry, a Pull Request must be created with the requirements pointed at the repository.


