#2 Create a task and don't prepay for it

Paying with funds in Action smart contract

Make sure to go through the previous tutorial before this!

In the previous example, we had to deposit some funds to the Task Treasury in order to pay for gas fees used for task executions.

Now let's explore another method which could save you that step! 😉

Using the same example, we have Counter.sol which we want to automate. We would need to make some changes to it and it will be named CounterWithoutTreasury.sol to avoid confusion.

Step 1 : Make changes and deploy Action smart contract

Here is the code for CounterWithoutTreasury.sol.

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

The function we are trying to automate - increaseCount(uint256 amount) now has the ability to pay Gelato whenever executors call increaseCount .

This is done by inheriting PokeMeReady and using the onlyPokeMe modifier in increaseCount . Note: This step is required unlike the previous Counter example.

_transfer has two parameters, fee and feeToken which has to be queried from the PokeMe contract by using getFeeDetails()

feeToken is set when submitting your task on the Gelato Website which we will cover later on.

Here is how PokeMeReady.sol looks like

// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.0;
import {
SafeERC20,
IERC20
} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
interface IPokeMe {
function gelato() external view returns (address payable);
}
abstract contract PokeMeReady {
address public immutable pokeMe;
address payable public immutable gelato;
address public constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
constructor(address _pokeMe) {
pokeMe = _pokeMe;
gelato = IPokeMe(_pokeMe).gelato();
}
modifier onlyPokeMe() {
require(msg.sender == pokeMe, "PokeMeReady: onlyPokeMe");
_;
}
function _transfer(uint256 _amount, address _paymentToken) internal {
if (_paymentToken == ETH) {
(bool success, ) = gelato.call{value: _amount}("");
require(success, "_transfer: ETH transfer failed");
} else {
SafeERC20.safeTransfer(IERC20(_paymentToken), gelato, _amount);
}
}
}

Step 2 : Deploy Resolver contract

There are no changes needed for the resolver contract! Here is the resolver contract.

// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.0;
import {IResolver} from "../interfaces/IResolver.sol";
interface ICounter {
function lastExecuted() external view returns (uint256);
function increaseCount(uint256 amount) external;
}
contract CounterResolver is IResolver {
// solhint-disable var-name-mixedcase
address public immutable COUNTER;
constructor(address _counter) {
COUNTER = _counter;
}
function checker()
external
view
override
returns (bool canExec, bytes memory execPayload)
{
uint256 lastExecuted = ICounter(COUNTER).lastExecuted();
// solhint-disable not-rely-on-time
canExec = (block.timestamp - lastExecuted) > 180;
execPayload = abi.encodeWithSelector(
ICounter.increaseCount.selector,
uint256(100)
);
}
}

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

Step 3 : Creating A Task

After deploying both CounterWithoutTreasury.sol and CounterResolver.sol . We can create a task on the Gelato Website.

Submitting a task is completely the same as before. The only difference is we have to opt out of "Use Treasury" here.

Here we have to input the address of feeToken previously mentioned, which will be used to pay Gelato.

If you would like to pay with ETH / MATIC / FTM, use 0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee as the token address.

Note: Only MATIC and FTM are available on Polygon and Fantom for now.

After submitting your task, you will be able to see the Fee Token you are using in your task information.