Gelato V2 & SuperFluid

Javier Donoso
Coinmonks
5 min readDec 31, 2022

--

Even easier to automate your streams in 2023!!

Gelato Automate

Gelato Network released in the past months a new version. Here you can find the changes and be ready to automate your streams.

The new Gelato Version V2 follows a modular approach that allows for more flexibility.

We are going to start with one of the most commons questions within the Superfluid #dev-support discord channel: "How to schedule to stop a stream?", although the functionality is implemented in the Superfluid dashboard, it is worth understanding how to do it programmatically.

Here you can find a walkthrough video.

As we are going to play around, let me introduce/refresh the 3x3 steps to get Gelato up and running:

  1. Wire Gelato infrastructure: The updates to our contract that allow communicating with Gelato Automate
  2. Funding Strategy: There are two alternative ways to pay the transactions; from Gelato Balance or each transaction pays for itself. We chose that each transaction pays for itself. We must only don't forget to fund the contract. More on payment can be seen here.
  3. Gelato Custom Logic: Including task creation, checker condition, and task to be executed.
    - Task creation can be done dynamically from a contract/SDK or through the Gelato Automate UI
    - The checker condition, in our case, is straightforward, as we only have to check the time to close the stream.
    - The executable function is also straightforward, as if we already created a stream, we know how to close it. We should keep in mind that the EOA/contract executing the close function has to be authorized by the stream owner to close the stream

Hands-On

The example repo can be found at:

We have different alternatives for how to start a stream: using the superfluid dashboard, SDK, or cfaLibrary within a contract.

Let's consider how we will close the stream, we must keep in mind that the Gelato Ops Contract will call the executable functionthe Gelato Ops Contract will call the executable function, and in Superfluid, only the sender or the receiver of a stream can close/stop the stream.

With the help of the Superfluid ACL (Access Control List), we could authorize a smart contract to stop the stream. This will make our life much easier as from the contract we could

Gelato

If we follow the above steps, we have to:

  1. Wire Gelato Infrastructure:
    We will copy the gelato folder to our contract Folder. We can find the files here. The folder structure should look like
Gelato Helper Contracts

Inherit the OpsReady contract

contract CloseStream is OpsReady {

constructor( address _ops )
OpsReady(_ops, address(this)){

}

2. Funding Strategy, the target contract we will pay for each transaction. We must fund our contract and ensure the fees are transferred to Gelato by Execution

3. Gelato Custom Logic
We will create our task dynamically from the contract. Let's look at the code we will use to create the task.

 taskId = ops.createTask(execAddress, execData, moduleData, ETH);

execAddress Address of the contract executing the task

exexData() The code that will be executed by the task

  bytes memory execData = 
abi.encodeWithSelector(this.closeStream.selector, sender,receiver);
// closeStream is the executable function

moduleData is how we configure our task. There are four configuration modules:
- Resolver: when we require custom logic to check if the function has to be executed.
- Time: when the executions will happen at a specific point in time
- Proxy: when we require a dedicated msg.sender.
- Single_exec: when we require only one execution

ETH Token for paying the transaction

In our use case, we will set the TimeModule and the SingleExec module, ensuring that the executable function runs at the required timestamp and only runs once (we only close the stream once). We build our ModuleData like this:

    bytes memory timeArgs = 
abi.encode(uint128(block.timestamp + duration), duration);

Module[] memory modules = new Module[](2);

modules[0] = Module.TIME;
modules[1] = Module.SINGLE_EXEC;

bytes[] memory args = new bytes[](1);

args[0] = timeArgs;

ModuleData memory moduleData = ModuleData(modules, args);

More info about modules can be found here

We won't require the checker condition.

The executable function will finally be:


function closeStream(address sender, address receiver) external onlyOps {

(uint256 fee, address feeToken) = ops.getFeeDetails();
_transfer(fee, feeToken); // fee transferred

_cfaLib.deleteFlow(sender, receiver, superToken);

taskId = bytes32(0);

}

Contract

Our contract:

So far, we have a contract ready to close streams. We must only create a stream, authorize our contract to stop the stream, and create the task to close the stream.

Scripts

Contract deploy:

yarn deploy goerli

The console will log something like this:

Close Stream deployed succsessfully 
at: 0xCC7FA88DB7df720EA72872ad7C19fd85026047d9

We will copy the deployed address into the ./scripts/Helpers.ts so it will be available later.

export const CloseStreamAddress = "0xCC7FA88DB7df720EA72872ad7C19fd85026047d9";

We will verify our contract to interact later with etherscan

yarn verify goerli // in scripts/verify.ts

We will now start a stream. We can do it with the SDK or directly from the Superfluid dashboard. With the SDK:

yarn startStream goerli // in scripts/startStream.ts

Authorize our smart contract to stop the stream

yarn authorizeControl goerli // in scripts/authorizeControl.ts

Create the Gelato task to close the stream

yarn createTaskStopStream goerli // in scripts/createTaskStopStream.ts

And if we look in the gelato app, we can see our task is already running

Voilà

If we wait some minutes, we will see the task execution, and our stream will be closed!

Conclusion

It is relatively simple to wire the gelato network into our smart contracts and unlock the full potential of automation. There are several ways of doing it. We have chosen the one that will be most used.

It is worth spending some time acquiring an helicopter view of how Superfluid and Gelato works

The Gelato V2 introduces the modules concept, which gives devs more flexibility in choosing how to configure the tasks. After the first time, encoding/decoding is straightforward.

This article can help other devs quickly get up and running with gelato and apply it to Superfluid streams.

Stay tuned in January, where with the help of Gelato off-chain resolvers we will answer to 0xFran.eth/lens Twitter!!

You can connect with me on Twitter @donoso_eth

Resources

Gelato

Gelato network
Gelato automate app
Gelato docs

Superfluid

Superfluid finance
Superfluid dashboard
Superfluid docs

Gelato V1 & Superfluid Super apps article

--

--