// SPDX-License-Identifier: MIT pragma solidity >=0.8.4 <0.9.0; /// @title Keep3rJobFundableCredits contract /// @notice Handles the addition and withdrawal of credits from a job interface IKeep3rJobFundableCredits { // Events /// @notice Emitted when Keep3rJobFundableCredits#addTokenCreditsToJob is called /// @param _job The address of the job being credited /// @param _token The address of the token being provided /// @param _provider The user that calls the function /// @param _amount The amount of credit being added to the job event TokenCreditAddition(address indexed _job, address indexed _token, address indexed _provider, uint256 _amount); /// @notice Emitted when Keep3rJobFundableCredits#withdrawTokenCreditsFromJob is called /// @param _job The address of the job from which the credits are withdrawn /// @param _token The credit being withdrawn from the job /// @param _receiver The user that receives the tokens /// @param _amount The amount of credit withdrawn event TokenCreditWithdrawal(address indexed _job, address indexed _token, address indexed _receiver, uint256 _amount); // Errors /// @notice Throws when the token is KP3R, as it should not be used for direct token payments error TokenUnallowed(); /// @notice Throws when the token withdraw cooldown has not yet passed error JobTokenCreditsLocked(); /// @notice Throws when the user tries to withdraw more tokens than it has error InsufficientJobTokenCredits(); // Variables /// @notice Last block where tokens were added to the job [job => token => timestamp] /// @return _timestamp The last block where tokens were added to the job function jobTokenCreditsAddedAt(address _job, address _token) external view returns (uint256 _timestamp); // Methods /// @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; /// @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; } /// @title Keep3rJobFundableLiquidity contract /// @notice Handles the funding of jobs through specific liquidity pairs interface IKeep3rJobFundableLiquidity { // Events /// @notice Emitted when Keep3rJobFundableLiquidity#approveLiquidity function is called /// @param _liquidity The address of the liquidity pair being approved event LiquidityApproval(address _liquidity); /// @notice Emitted when Keep3rJobFundableLiquidity#revokeLiquidity function is called /// @param _liquidity The address of the liquidity pair being revoked event LiquidityRevocation(address _liquidity); /// @notice Emitted when IKeep3rJobFundableLiquidity#addLiquidityToJob function is called /// @param _job The address of the job to which liquidity will be added /// @param _liquidity The address of the liquidity being added /// @param _provider The user that calls the function /// @param _amount The amount of liquidity being added event LiquidityAddition(address indexed _job, address indexed _liquidity, address indexed _provider, uint256 _amount); /// @notice Emitted when IKeep3rJobFundableLiquidity#withdrawLiquidityFromJob function is called /// @param _job The address of the job of which liquidity will be withdrawn from /// @param _liquidity The address of the liquidity being withdrawn /// @param _receiver The receiver of the liquidity tokens /// @param _amount The amount of liquidity being withdrawn from the job event LiquidityWithdrawal(address indexed _job, address indexed _liquidity, address indexed _receiver, uint256 _amount); /// @notice Emitted when Keep3rJobFundableLiquidity#addLiquidityToJob function is called /// @param _job The address of the job whose credits will be updated /// @param _rewardedAt The time at which the job was last rewarded /// @param _currentCredits The current credits of the job /// @param _periodCredits The credits of the job for the current period event LiquidityCreditsReward(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits, uint256 _periodCredits); /// @notice Emitted when Keep3rJobFundableLiquidity#forceLiquidityCreditsToJob function is called /// @param _job The address of the job whose credits will be updated /// @param _rewardedAt The time at which the job was last rewarded /// @param _currentCredits The current credits of the job event LiquidityCreditsForced(address indexed _job, uint256 _rewardedAt, uint256 _currentCredits); // Errors /// @notice Throws when the liquidity being approved has already been approved error LiquidityPairApproved(); /// @notice Throws when the liquidity being removed has not been approved error LiquidityPairUnexistent(); /// @notice Throws when trying to add liquidity to an unapproved pool error LiquidityPairUnapproved(); /// @notice Throws when the job doesn't have the requested liquidity error JobLiquidityUnexistent(); /// @notice Throws when trying to remove more liquidity than the job has error JobLiquidityInsufficient(); /// @notice Throws when trying to add less liquidity than the minimum liquidity required error JobLiquidityLessThanMin(); // Structs /// @notice Stores the tick information of the different liquidity pairs struct TickCache { int56 current; // Tracks the current tick int56 difference; // Stores the difference between the current tick and the last tick uint256 period; // Stores the period at which the last observation was made } // Variables /// @notice Lists liquidity pairs /// @return _list An array of addresses with all the approved liquidity pairs function approvedLiquidities() external view returns (address[] memory _list); /// @notice Amount of liquidity in a specified job /// @param _job The address of the job being checked /// @param _liquidity The address of the liquidity we are checking /// @return _amount Amount of liquidity in the specified job function liquidityAmount(address _job, address _liquidity) external view returns (uint256 _amount); /// @notice Last time the job was rewarded liquidity credits /// @param _job The address of the job being checked /// @return _timestamp Timestamp of the last time the job was rewarded liquidity credits function rewardedAt(address _job) external view returns (uint256 _timestamp); /// @notice Last time the job was worked /// @param _job The address of the job being checked /// @return _timestamp Timestamp of the last time the job was worked function workedAt(address _job) external view returns (uint256 _timestamp); // Methods /// @notice Returns the liquidity credits of a given job /// @param _job The address of the job of which we want to know the liquidity credits /// @return _amount The liquidity credits of a given job function jobLiquidityCredits(address _job) external view returns (uint256 _amount); /// @notice Returns the credits of a given job for the current period /// @param _job The address of the job of which we want to know the period credits /// @return _amount The credits the given job has at the current period function jobPeriodCredits(address _job) external view returns (uint256 _amount); /// @notice Calculates the total credits of a given job /// @param _job The address of the job of which we want to know the total credits /// @return _amount The total credits of the given job function totalJobCredits(address _job) external view returns (uint256 _amount); /// @notice Calculates how many credits should be rewarded periodically for a given liquidity amount /// @dev _periodCredits = underlying KP3Rs for given liquidity amount * rewardPeriod / inflationPeriod /// @param _liquidity The liquidity to provide /// @param _amount The amount of liquidity to provide /// @return _periodCredits The amount of KP3R periodically minted for the given liquidity function quoteLiquidity(address _liquidity, uint256 _amount) external view returns (uint256 _periodCredits); /// @notice Observes the current state of the liquidity pair being observed and updates TickCache with the information /// @param _liquidity The liquidity pair being observed /// @return _tickCache The updated TickCache function observeLiquidity(address _liquidity) external view returns (TickCache memory _tickCache); /// @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; /// @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; /// @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; /// @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; /// @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; } /// @title Keep3rJobManager contract /// @notice Handles the addition and withdrawal of credits from a job interface IKeep3rJobManager { // Events /// @notice Emitted when Keep3rJobManager#addJob is called /// @param _job The address of the job to add /// @param _jobOwner The job's owner event JobAddition(address indexed _job, address indexed _jobOwner); // Errors /// @notice Throws when trying to add a job that has already been added error JobAlreadyAdded(); /// @notice Throws when the address that is trying to register as a keeper is already a keeper error AlreadyAKeeper(); // Methods /// @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; } /// @title Keep3rJobWorkable contract /// @notice Handles the mechanisms jobs can pay keepers with along with the restrictions jobs can put on keepers before they can work on jobs interface IKeep3rJobWorkable { // Events /// @notice Emitted when a keeper is validated before a job /// @param _gasLeft The amount of gas that the transaction has left at the moment of keeper validation event KeeperValidation(uint256 _gasLeft); /// @notice Emitted when a keeper works a job /// @param _credit The address of the asset in which the keeper is paid /// @param _job The address of the job the keeper has worked /// @param _keeper The address of the keeper that has worked the job /// @param _amount The amount that has been paid out to the keeper in exchange for working the job /// @param _gasLeft The amount of gas that the transaction has left at the moment of payment event KeeperWork(address indexed _credit, address indexed _job, address indexed _keeper, uint256 _amount, uint256 _gasLeft); // Errors /// @notice Throws if the address claiming to be a job is not in the list of approved jobs error JobUnapproved(); /// @notice Throws if the amount of funds in the job is less than the payment that must be paid to the keeper that works that job error InsufficientFunds(); // Methods /// @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); /// @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); /// @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; /// @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; /// @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; } /// @title Keep3rJobOwnership contract /// @notice Handles the ownership of the jobs interface IKeep3rJobOwnership { // Events /// @notice Emitted when Keep3rJobOwnership#changeJobOwnership is called /// @param _job The address of the job proposed to have a change of owner /// @param _owner The current owner of the job /// @param _pendingOwner The new address proposed to be the owner of the job event JobOwnershipChange(address indexed _job, address indexed _owner, address indexed _pendingOwner); /// @notice Emitted when Keep3rJobOwnership#JobOwnershipAssent is called /// @param _job The address of the job which the proposed owner will now own /// @param _previousOwner The previous owner of the job /// @param _newOwner The newowner of the job event JobOwnershipAssent(address indexed _job, address indexed _previousOwner, address indexed _newOwner); // Errors /// @notice Throws when the caller of the function is not the job owner error OnlyJobOwner(); /// @notice Throws when the caller of the function is not the pending job owner error OnlyPendingJobOwner(); // Variables /// @notice Maps the job to the owner of the job (job => user) /// @return _owner The addres of the owner of the job function jobOwner(address _job) external view returns (address _owner); /// @notice Maps the owner of the job to its pending owner (job => user) /// @return _pendingOwner The address of the pending owner of the job function jobPendingOwner(address _job) external view returns (address _pendingOwner); // Methods /// @notice Proposes a new address to be the owner of the job function changeJobOwnership(address _job, address _newOwner) external; /// @notice The proposed address accepts to be the owner of the job function acceptJobOwnership(address _job) external; } /// @title Keep3rJobMigration contract /// @notice Handles the migration process of jobs to different addresses interface IKeep3rJobMigration { // Events /// @notice Emitted when Keep3rJobMigration#migrateJob function is called /// @param _fromJob The address of the job that requests to migrate /// @param _toJob The address at which the job requests to migrate event JobMigrationRequested(address indexed _fromJob, address _toJob); /// @notice Emitted when Keep3rJobMigration#acceptJobMigration function is called /// @param _fromJob The address of the job that requested to migrate /// @param _toJob The address at which the job had requested to migrate event JobMigrationSuccessful(address _fromJob, address indexed _toJob); // Errors /// @notice Throws when the address of the job that requests to migrate wants to migrate to its same address error JobMigrationImpossible(); /// @notice Throws when the _toJob address differs from the address being tracked in the pendingJobMigrations mapping error JobMigrationUnavailable(); /// @notice Throws when cooldown between migrations has not yet passed error JobMigrationLocked(); // Variables /// @notice Maps the jobs that have requested a migration to the address they have requested to migrate to /// @return _toJob The address to which the job has requested to migrate to function pendingJobMigrations(address _fromJob) external view returns (address _toJob); // Methods /// @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; /// @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; } /// @title Keep3rJobDisputable contract /// @notice Handles the actions that can be taken on a disputed job interface IKeep3rJobDisputable is IKeep3rJobFundableCredits, IKeep3rJobFundableLiquidity { // Events /// @notice Emitted when Keep3rJobDisputable#slashTokenFromJob is called /// @param _job The address of the job from which the token will be slashed /// @param _token The address of the token being slashed /// @param _slasher The user that slashes the token /// @param _amount The amount of the token being slashed event JobSlashToken(address indexed _job, address _token, address indexed _slasher, uint256 _amount); /// @notice Emitted when Keep3rJobDisputable#slashLiquidityFromJob is called /// @param _job The address of the job from which the liquidity will be slashed /// @param _liquidity The address of the liquidity being slashed /// @param _slasher The user that slashes the liquidity /// @param _amount The amount of the liquidity being slashed event JobSlashLiquidity(address indexed _job, address _liquidity, address indexed _slasher, uint256 _amount); // Errors /// @notice Throws when the token trying to be slashed doesn't exist error JobTokenUnexistent(); /// @notice Throws when someone tries to slash more tokens than the job has error JobTokenInsufficient(); // Methods /// @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 _token The address of the token that will be slashed /// @param _amount The amount of the token that will be slashed function slashTokenFromJob( address _job, address _token, uint256 _amount ) external; /// @notice Allows governance or a slasher to slash liquidity from a job /// @param _job The address being slashed /// @param _liquidity The address of the liquidity that will be slashed /// @param _amount The amount of liquidity that will be slashed function slashLiquidityFromJob( address _job, address _liquidity, uint256 _amount ) external; } // solhint-disable-next-line no-empty-blocks interface IKeep3rJobs is IKeep3rJobOwnership, IKeep3rJobDisputable, IKeep3rJobMigration, IKeep3rJobManager, IKeep3rJobWorkable { }