LogoLogo
  • 🌊Superfluid
  • Protocol Overview
    • 💡What is Superfluid?
    • 📄In-Depth Overview
      • Super Tokens
      • Super Agreements
        • 🚰Money Streaming (CFA)
        • ✳️Distributions (IDA)
        • 🌊Streaming Distributions
      • Super Apps
      • Superfluid Host
    • 🧠Use Cases
      • Recurring Payments
      • DeFi
      • Social & Community
      • Gaming
    • 📔Glossary of Terms
  • Developers
    • 🏃Quickstart
    • 🪙Super Tokens
      • Super Tokens - Solidity
      • Super Tokens - SDK Core
      • Super Tokens - Frontend Examples
      • Types of Super Tokens
      • Deploy a Super Token
        • Deploying a Wrapper Super Token
        • Deploying a Self Governed Super Token
        • Deploying a Pure Super Token
      • In-Depth
        • Tracking Super Token Balances
        • ERC777 in Super Tokens
      • Test Super Token Faucet
    • 🌊Money Streaming (CFA)
      • Solidity
        • Read Methods
          • getFlowInfo
          • getFlowRate
          • getNetFlowRate
        • Write Methods
          • createFlow
          • updateFlow
          • deleteFlow
          • With User Data
          • With Context
      • SDK Core
        • Read Methods
          • getFlow
          • getNetFlow
          • getAccountFlowInfo
        • Write Methods
          • createFlow
          • updateFlow
          • deleteFlow
      • Access Control List (ACL)
        • Solidity
          • createFlowFrom
          • updateFlowFrom
          • deleteFlowFrom
          • setFlowPermissions
          • setMaxFlowPermissions
          • revokeFlowPermissions
          • increaseFlowRateAllowanceWithPermissions
          • decreaseFlowRateAllowanceWithPermissions
          • getFlowPermissions
        • SDK Core
          • createFlowByOperator
          • updateFlowByOperator
          • deleteFlowByOperator
          • updateFlowOperatorPermissions
          • revokeFlowOperatorPermissions
          • increaseFlowRateAllowanceWithPermissions
          • getFlowOperatorData
      • Frontend Examples
      • More...
        • Flow Rate Time Frames
        • Building Batched Streams in Safe
        • Flow NFTs
    • ✳️Distributions (IDA)
      • IDA - Solidity
      • IDA - SDK Core
      • IDA - Frontend Examples
    • 🤖Super Apps
      • Super Apps in Depth
      • Super App Callbacks
        • Calling Agreements In Super Apps
      • User Data
        • NFT Billboard Example
      • SuperAppBaseFlow
      • Super App Examples
      • Super App Deployment Guide
    • 🧺Batch Calls
      • Batch Calls - SDK Core
      • Batch Calls - Frontend Examples
    • ⚙️Automations
      • Auto-Wrap
        • Dev Guide
      • Stream Scheduler
        • Dev Guide
      • Vesting Scheduler
        • Dev Guide
      • Stream Accounting API
        • Dev Guide
      • Automation Subgraphs
        • Stream Scheduler Subgraph
        • Vesting Scheduler Subgraph
        • Auto Wrap Subgraph
    • 🏗️Integration Guides
      • For Your Integration: The Basics
        • Supporting Super Tokens
        • Supporting Money Streams
        • Supporting Instant Distributions
      • Gating with Superfluid Subscriptions & Guild.xyz
      • Displaying Token Balances
      • Useful Queries for Your Integration
        • Instant Distribution Events
        • Money Streaming Events
        • Super Token Events
        • Other Helpful Queries
      • Constructing Links to The Superfluid Dashboard
    • 🔁Superfluid Subscriptions
      • Superfluid Checkout Widget
      • Implementing Subscriptions in your App
    • SDK Core General
      • Initialization
      • Functionality
      • Getting Data
      • Resolver
      • Reference Docs
    • Solidity General
      • Calling Super Agreements
      • Libraries
      • Resolver
    • Testing Guide
      • Hardhat Testing
      • Foundry Testing
      • In-Depth
        • Hardhat Mainnet Fork Testing
        • Super App Testing on Mainnet Forks
    • Subgraph
    • Reference
      • Deploying The Framework
      • EVM Contracts
      • SDK Redux
      • Superfluid Console
      • Superfluid Protocol Addresses
    • Contract Addresses
  • Sentinels
    • 🥅Liquidations & TOGA
    • 🤖Running a Sentinel
    • 🗺️Solvency Dashboard
  • Resources
    • 🌊Superfluid Wave Pool
    • 📜Superfluid on Ethereum Mainnet
    • 💰Bounty Program
    • 🛡️Security & Bug Bounties
    • 💡Project Ideas
    • 🗳️Token Dashboard Submission
    • 🎥Videos
    • Superfluid Deployment Guide
    • Learn about Ethereum
    • Code of Conduct
Powered by GitBook
On this page
  • Working With Superfluid Using Solidity
  • Common Mistakes

Was this helpful?

  1. Developers
  2. Solidity General

Calling Super Agreements

Using Superfluid at the Smart Contract Level

PreviousSolidity GeneralNextLibraries

Last updated 2 years ago

Was this helpful?

Working With Superfluid Using Solidity

When you open a stream or make use of instant distributions, what you're really doing is interacting with Superfluid agreements. Money streams are created by interacting with the , while calls related to instant distributions are done by working with the .

NOTE: the easiest way to create money streams or work with the IDA in solidity is via the CFAv1 Library and IDAv1 Library.

To get started, you'll need to be sure to import, at minimum, the Superfluid host interface & agreement interface that you'd like to work with. In a situation where you'd like to use both the CFA and IDA in the same contract, you would import these contracts like this:

pragma solidity ^0.8.0

import { ISuperfluid }from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol"; //"@superfluid-finance/ethereum-monorepo/packages/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol";

import { IConstantFlowAgreementV1 } from "@superfluid-finance/ethereum-contracts/contracts/interfaces/agreements/IConstantFlowAgreementV1.sol";

import { IInstantDistributionAgreementV1 } from "@superfluid-finance/ethereum-contracts/contracts/interfaces/agreements/IInstantDistributionAgreementV1.sol";

If you'd like to interact with a Superfluid agreement directly by using solidity, you need to make a function call first to the Superfluid host contract. You'll call the callAgreement or callAgreementWithContext function on the host contract (), and pass in a few parameters:

ISuperAgreement agreementClass - the the agreement you're going to interact with (either the CFA or IDA)

bytes memory calldata - the transaction you're calling on the agreement you're interacting with, compiled to bytecode (using one of solidity's )

bytes memory userData - any additional data you'd like to include with your function call. If you don't plan to add userData, you can pass in an empty bytes value (i.e. "0x"). You can learn more about this parameter .

Here's an example of how this looks in action when interacting with the constant flow agreement. This pattern will be the same whether you're creating, updating, or deleting flows.

//creating a flow in pure solidity
host.callAgreement(
    cfa,
    abi.encodeWithSelector(
        cfa.createFlow.selector,
        token,
        receiver,
        flowRate,
        new bytes(0) // placeholder - always pass in bytes(0)
    ),
    "0x" //userData
);

The following is an example for interacting with the instant distribution agreement using solidity. This pattern is the same for each interaction you'd like to make with the IDA:

// distributing tokens with the instant distribution agreement
host.callAgreement(
    ida,
    abi.encodeWithSelector(
        ida.distribute.selector,
        token,
        index,
        amountToDistribute,
        new bytes(0) // placeholder ctx
    ),
    "0x" // user data
);

Common Mistakes

One other thing to keep in mind is the value of msg.sender when working with Superfluid from a contract. For example, developers will occasionally want to create a function which will let an account create a flow into the contract itself. So, they'll write a function that looks like this, expecting it to create a flow into the contract from the msg.sender of the function:

//this will fail because a contract cannot create a flow to itself

function createFlowFail(ISuperToken DAIx, int96 flowRate) external {
    cfaV1.createFlow(address(this), DAIx, flowRate);
}

In the above function, you have set the receiver on the cfaV1.createFlow function to be the contract's address. Under the hood, even though msg.sender on the broader createFlowFail function is an external address, the msg.sender on the cfa.createFlow call to the Superfluid protocol is the address of the contract. The Superfluid callAgreement function will see that the contract is trying to create a flow into itself, and revert.

A similar mistake which stems from this msg.sender misunderstanding occurs when developers want to allow external accounts to create flows directly to other accounts via a function on the contract. For example:

//remember that this will revert if the contract has a zero balance of DAIx
//msg.sender on the call to the Superfluid framework is the contract

function createFlow2Receiver(address receiver, ISuperToken DAIx, int96 flowRate) external {
    cfaV1.createFlow(receiver, DAIx, flowRate);
}

Recall that the value of msg.sender on the cfaV1.createFlow function will be the contract's address, not the external address calling the broader createFlow2Receiver function. If you're intending to create a flow from the contract to another address, then this code is what you need (just make sure your contract has a balance of Super tokens!). However, if you're running this with the expectation that it will open a flow directly from an external account calling the function to the intended receiver, it will not work as expected.

NOTE: If you're interacting with agreements inside of a Super App callback, this process will work differently. See for details.

If you want to create a flow into a contract, we recommend that you use either the from outside of a contract or a 2nd contract which already has some balance of Super Tokens.

constant flow agreement (CFA)
instant distribution agreement (IDA)
Superfluid.sol
encoding methods
here
this section
Core-SDK