Keepers-compatible contracts
Overview
Learn how to make smart contracts Keepers-compatible with the arkadiko-automation-trait-v1
trait and its functions.
Example Contract
Keepers-compatible contracts must meet the following requirements:
Implement trait
arkadiko-automation-trait-v1
. You can refer to the Arkadiko Contracts on GitHub to find the trait interface.The automation trait has three functions that need to be implemented:
initialize
,check-job
andrun-job
Include a read-only
check-job
function that contains the logic that will be executed off-chain to see ifrun-job
should be executed. Therun-job
function can use on-chain data from any other Clarity smart contract, including use of theat-block
function to access historical data.Include a public
run-job
function that will be executed on-chain whencheck-job
returns(ok true)
.
After you register the contract as an Arkadiko Job, the Keepers Network simulates the check-job
read-only function off-chain during every block to determine if the job needs to run. When check-job
returns (ok true)
, the Keepers Network calls run-job
on-chain and charges 10 DIKO plus the STX gas fee from your account. This cycle repeats until the job is cancelled or runs out of funding.
In the above example, we would like to add an amount of DIKO tokens to the Arkadiko liquidation pool which is used as rewards for people depositing USDA. More information about the liquidation pool can be found here. Let's analyze the above lines of code.
On line 2, we import the arkadiko automation trait that will require us to implement the three required methods: initialize, check-job and run-job. In this case, we don't need any initialization logic (which you need to execute yourself on deployment), so we simply return (ok true).
The check-job read-only function will call an Arkadiko read-only function to get the end-epoch-block
. Or in other words, we get the block height at which we should add new DIKO to the liquidation rewards. Alternatively, we could have also written custom logic in this smart contract to keep the last block execution and execute it every 1008 blocks. When the current block-height
is greater or equal to the end-epoch-block
height, we should return (ok true)
. Otherwise, we return (ok false)
.
IMPORTANT: Your check-job function should never return an error (e.g. (err false)), since that would make the whole execution process fail. Simply return (ok true) or (ok false)
The run-job public function simply executes the transfer of DIKO through a liquidation rewards contract and returns (ok true). Always end your execution with an error code or an ok code.
Best practices
Trigger ONLY when conditions are met
Some actions must be performed only when specific conditions are met. Check all of the preconditions within check-job
and run-job
as well to ensure that state change occurs only when necessary.In this pattern, it is undesirable for the state change to occur until the next time the Arkadiko Job is checked by the network and the conditions are met. It is a best practice to stop any state change or effects by performing the same checks or similar checks that you use in check-job
. These checks validate the conditions before doing the work.For example, if you have a contract where you create a block-height based timer in check-job
that is designed to start a transfer at a specific time, validate the condition to ensure third-party calls to your run-job
function do not start the transfer at a different block height.
Trigger ONLY when data is verified
Some actions must be performed using data you intend to use. Validated that the run-job
function is allowed before execution.For example, if you have a run-job
that funds a wallet, ensure you have a list of permissable addresses to compare against to prevent third-party calling your function to send money to their address.
When triggering is not harmful
Sometimes actions must be performed when conditions are met, but performing actions when conditions are not met is still acceptable. Condition checks within run-job
might not be required, but it can still be a good practice to short circuit expensive and unnecessary on-chain processing when it is not required.It might be desirable to call run-job
when the check-job
conditions haven't yet been tested by Arkadiko Keepers, so any specific checks that you perform are entirely use case specific.
Test your contract
As with all smart contract testing, it is important to test the boundaries of your smart contract in order to ensure it operates as intended. Similarly, it is important to make sure your Keepers-compatible contract operates within the parameters of the Job Registry.Test all of your mission-critical contracts, and stress-test the contract to confirm the performance and correct operation of your use case under load and adversarial conditions. The Arkadiko Keeper Network will continue to operate under stress, but so should your contract.
Last updated