Using the IbAlluo contract directly to create streams

Creating a stream directly through the IbAlluo contract allows you to bypass manually wrapping and approving the StIbAlluo contract.

1. Grant Permissions first!

To do so, you must grant permissions to the IbAlluo contract as a stream operator for your account. One way you can do this is through hardhat by instantiating an IbAlluo contract, using formatPermissions to get the callData and then calling the Superfluid Host contract with the following parameters. This only needs to be done once for each IbAlluo contract when initially making a stream.

/// @notice Formats permissios so users can approve the ibAlluo contract as an operator of streams
/// @dev This can be removed once the frontend hardcodes the function call / does it inside ethers.js.
function formatPermissions() public view returns (bytes memory) {
     return abi.encodeCall(
                new bytes(0)
Example on polygon
let encodeData = await ibAlluoCurrent.formatPermissions();
let superhost = await ethers.getContractAt("Superfluid", "0x3E14dC1b13c488a8d5D310918780c983bD5982E7");
await superhost.callAgreement(

2. Once permissions are granted, now call the createFlow function

/// @notice Wraps and creates flow 
/// @dev Forces transfer of ibAlluo to the StIbAlluo contract then mints StIbAlluos to circumvent having to sign multiple transactions to create streams
/// @param receiver The recipient of the streamed flow
/// @param flowRate The amount of ibAlluos per second to be streamed (decimals 10**18)
/// @param toWrap The amount of ibAlluos to automatically wrap (recommend wrapping entire ibALluo balance initially)
function createFlow(address receiver, int96 flowRate, uint256 toWrap) external {
    _transfer(msg.sender, address(this), toWrap);
    _approve(address(this), superToken, toWrap);
    IAlluoSuperToken(superToken).upgradeTo(msg.sender, toWrap, "");
    cfaV1Lib.createFlowByOperator( msg.sender, receiver, ISuperfluidToken(superToken), flowRate);
    ISuperfluidResolver(superfluidResolver).addToChecker(msg.sender, receiver);
    emit CreateFlow(msg.sender, receiver, flowRate);
function stopFlowWhenCritical(address sender, address receiver) external onlyRole(DEFAULT_ADMIN_ROLE) {
    cfaV1Lib.deleteFlowByOperator(sender, receiver, ISuperfluidToken(superToken));
    emit DeletedFlow(sender, receiver);
function forceWrap(address sender) external onlyRole(DEFAULT_ADMIN_ROLE) {
    uint256 balance = balanceOf(address(sender));
    _transfer(sender, address(this), balance);
    _approve(address(this), superToken, balance);
    IAlluoSuperToken(superToken).upgradeTo(sender, balance, "");

Calling createFlow will force transfer IbAlluos and then the IbAlluo contract will upgrade on your behalf and mint you StIbAlluos. Then, a flow will be created with the parameters you specified.

When creating a stream through the IbAlluo contract, the Alluo protocol protects you from liquidations: addToChecker() adds you to a list of users that a gelato resolver will check for liquidation risk. This means that whenever your StIbAlluo balance is low, a resolver will either call forceWrap() so you don't get accidentally liquidated, or close the stream entirely using stopFlowWhenCritical().

To illustrate this with examples:

  • Case 1: Stream close to liquidation but with enough IbAlluo balance to cover it.

You have 100 IbAlluos and 100 StIbAlluos with an outgoing stream of 20 IbAlluos per hour. You are 1 hour away from being liquidated by the superfluid protocol (including the deposit initially taken).

The Alluo resolver will realise that you have 100 IbAlluo to continue the stream and therefore wrap the IbAlluo to StIbAlluo - leaving you with 0 IbAlluo and 200 StIbAlluo to continue the stream.

  • Case 2: Stream close to liquidation but without enough IbAlluo balance to cover it.

You have 0 IbAlluos and 100 StIbAlluos with an outgoing stream of 20 IbAlluos per hour. You are 1 hour away from being liquidated by the superfluid protocol (including the deposit initially taken). The Alluo protocol will close your stream 1 hour prematurely to prevent your 80 StIbAlluos from being taken as a liquidation fee.

Last updated