Batching Functions
A neat feature of Sablier Flow is the ability to batch multiple function calls into a single transaction. This is made
possible by the Batch
contract, which is inherited by
SablierFlow
. With this, you can efficiently batch multiple function calls in a single transaction.
The code in this guide is not production-ready, and is implemented in a simplistic manner for the purpose of learning.
Set up a contract
Declare the Solidity version used to compile the contract:
pragma solidity >=0.8.22;
Import the relevant symbols:
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { ud21x18, UD21x18 } from "@prb/math/src/UD21x18.sol";
import { ud60x18 } from "@prb/math/src/UD60x18.sol";
import { Broker, ISablierFlow } from "@sablier/flow/src/interfaces/ISablierFlow.sol";
Create a contract called FlowBatchable
, and declare a constant USDC
of type IERC20
and a constant FLOW
of type
ISablierFlow
:
contract FlowBatchable {
IERC20 public constant USDC = IERC20(0xf08A50178dfcDe18524640EA6618a1f965821715);
ISablierFlow public constant FLOW = ISablierFlow(0x3a1beA13A8C24c0EA2b8fAE91E4b2762A59D7aF5);
}
In the code above, the contract addresses are hard-coded for demonstration purposes. However, in production, you would likely use input parameters to allow flexibility in changing the addresses.
Also, these addresses are deployed on Sepolia. If you need to work with a different chain, Flow addresses can be obtained from the Deployment Addresses page.
Create multiple streams
One of the most useful features achieved by batch
is the ability to create multiple streams in a single transaction.
Let's focus on it in this example.
Define a function that creates multiple streams and returns their respective stream IDs:
function createMultiple() external returns (uint256[] memory streamIds) {
// ...
}
Parameters
We will create two streams with same stream parameters required by the create
function.
address sender = msg.sender;
address firstRecipient = address(0xCAFE);
address secondRecipient = address(0xBEEF);
UD21x18 firstRatePerSecond = ud21x18(0.0001e18);
UD21x18 secondRatePerSecond = ud21x18(0.0002e18);
bool transferable = true;
Construct an array of bytes
of length 2 to be passed into the batch
function:
bytes[] memory calls = new bytes[](2);
calls[0] = abi.encodeCall(FLOW.create, (sender, firstRecipient, firstRatePerSecond, USDC, transferable));
calls[1] = abi.encodeCall(FLOW.create, (sender, secondRecipient, secondRatePerSecond, USDC, transferable));
Since we are creating two streams, the function will return an array containing the two generated stream IDs:
uint256 nextStreamId = FLOW.nextStreamId();
streamIds = new uint256[](2);
streamIds[0] = nextStreamId;
streamIds[1] = nextStreamId + 1;
Execute the batch
:
FLOW.batch(calls);
Homework
Try to implement the following ideas using batch
function:
- Adjust Rate Per Second and Deposit
- Pause and Withdraw Max
- Void and Withdraw Max
- Multiple Withdraw Max
Below, you will find the full code for it.
Other ideas
There are plenty of other possibilities as well! Feel free to experiment and come up with combinations that suit your system. 🚀
Full code
Below you can see the complete FlowBatchable
contract:
loading...