#1 Create a task and prepay for it

Paying with funds in Task Treasury

Step 1: Write & deploy the Action smart contract you want to automate

An Action is a smart contract that Gelato should automatically execute a function on based on certain conditions being fulfilled. The action can be an already deployed smart contract or you can write and deploy a new one. In this tutorial, our Action smart contract is the Counter.sol contract. It has a require that makes sure that the increaseCount() function can only be called every 3 minutes, which we will be referring to as the "condition".

If you write a smart contract that should be executed by Gelato, make sure you encode the condition that regulates WHEN the execution should occur (e.g. every 3 minutes) into the function of the action itself, using for example a requirestatement.

// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.0;
import { PokeMeReady } from "./PokeMeReady.sol";
contract Counter is PokeMeReady {
uint256 public count;
uint256 public lastExecuted;
constructor(address payable _pokeMe) PokeMeReady(_pokeMe) {}
function increaseCount(uint256 amount) external onlyPokeMe {
require(
((block.timestamp - lastExecuted) > 180),
"Counter: increaseCount: Time not elapsed"
);
count += amount;
lastExecuted = block.timestamp;
}
}

To add security to the contract, it should inherit PokeMeReady.sol which has the onlyPokeMe modifier. Use onlyPokeMe in the function which you want Gelato to call. Note: This step is optional but best to do it.

// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.0;
abstract contract PokeMeReady {
address payable public immutable pokeMe;
constructor(address payable _pokeMe) {
pokeMe = _pokeMe;
}
modifier onlyPokeMe() {
require(msg.sender == pokeMe, "PokeMeReady: onlyPokeMe");
_;
}
}

The action function can be named whatever you like and can have arbitrary arguments.

Step 2: Write and deploy a Resolver smart contract

A Resolver is a smart contract which tells Gelato: a) when to execute the action smart contract (e.g. Counter.sol) b) which function to execute on the action (e.g. increaseCount(uint256)) c) what inputs to use to execute that function (e.g. 100).

Here is an example of how a CounterResolver.sol contract might look like:

// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.0;
interface ICounter {
function lastExecuted() external view returns (uint256);
function increaseCount(uint256 amount) external;
}
contract CounterResolver {
address public immutable COUNTER;
constructor(address _counter) {
COUNTER = _counter;
}
function checker()
external
view
returns (bool canExec, bytes memory execPayload)
{
uint256 lastExecuted = ICounter(COUNTER).lastExecuted();
canExec = (block.timestamp - lastExecuted) > 180;
execPayload = abi.encodeWithSelector(
ICounter.increaseCount.selector,
uint256(100)
);
}
}

In this case, the resolver checks that at least 180 seconds (3 minutes) have passed since the last execution. If so, the function will return true as the canExec boolean, indicating to Gelato that it should execute the incrementCount() function on the Counter.sol action by passing 100 as the amount which will increment the count by 100.

Resolvers are called off-chain by Gelato bots in order to understand a) if the action smart contract is executable and b) what data to use to execute it. The most important part of the resolver contract is that it has one function that Gelato bots should call that returns 2 return values:

  • bool canExec true if Gelato should execute, false if Gelato should not execute

  • bytes memory execPayload The function selector of the function to call on the action and the encoded data that should be used to call that function.

Pro Tip 1: In order to return the execPayload use solidities abi.encodeWithSelector or abiEncodeWithSignature functions

After deploying Counter and CounterResolver , make sure to verify your contracts on Etherscan/ Polygonscan/ FtmScan. This will make creating your task a lot easier!

Step 3: Create a Task

This was everything that you needed to do in solidity. Now in order to task Gelato bots to automatically call your desired function on your action smart contract every time the canExec return value of your resolver contract returns true, you have to create a task on the Gelato Website.

Here you can see a Leader Board which shows all the tasks which are currently running and being monitored by Gelato.

By navigating to My Tasks you can see an overview of your scheduled tasks and the balance you have on Gelato which will be used to pay for the transaction fees.

In order to create a new task, navigate to Submit Task

  • Pick a name for your task.

  • Enter your Action address (address of Counter.sol) which you have deployed as the "Execution Address".

  • Select the function that Gelato should automate on your behalf, in this case the increaseCount() function.

Now enter the address of your Resolver, in this case the address for CounterResolver.sol.

After that, you should be prompted with another function selector, which enables you to select the resolver function checker() which returns the canExec boolean and the desired payload used to execute the increaseCount()function.

Step 4: Deposit Funds to pay for the execution

Transactions on e.g. Ethereum are not free. Gelato bots pay the transaction fee to miners and thus need to get their costs refunded + a small incentive added to make it worth operating the infrastructure. In general, on Ethereum mainnet, if a transaction would cost $10 doing it yourself, then it will cost roughly $11-12 using Gelato, the margin on top being the incentive that goes to bot operators.

For networks like Polygon, Gelato charges a fixed fee per transaction which you can check out by calling maxFee() on the respective TaskTreasury.sol smart contract.

In order to pay Gelato bots for every execution, you can simply deposit some ETH, USDC, DAI or any other ERC20 token on the TaskTreasury contract which will be automatically deducted with every execution that Gelato bots conduct on your behalf.

You can find the TaskTreasury contract addresses here.

In order to deposit ETH for your transactions, navigate to Manage Funds.

Choose the token you want to deposit and the amount. Click on Deposit Funds.

On Polygon and Fantom, only MATIC and FTM are accepted as payment for now.

Congratulations, you just created your first Task on Gelato 🎉🎉🎉Bots will now start monitoring your Resolver contract and if your Resolver function returns true, they will execute your Action contract.

You can view your list of tasks by navigating to My Tasks.

By clicking into a task, you can also view and monitor the executed transactions.

If you have any problems with your task, feel free to reach out to us in Telegram or Discord, we are happy to dive into your code and help you out!