# Table of Contents
- [Superfluid | Stream Money Every Second | Superfluid | Stream Money Every Second](#superfluid-stream-money-every-second-superfluid-stream-money-every-second)
- [What is Superfluid? | Superfluid | Stream Money Every Second](#what-is-superfluid-superfluid-stream-money-every-second)
- [Quickstart | Superfluid | Stream Money Every Second](#quickstart-superfluid-stream-money-every-second)
- [Quickstart | Superfluid | Stream Money Every Second](#quickstart-superfluid-stream-money-every-second)
- [Governance Overview | Superfluid | Stream Money Every Second](#governance-overview-superfluid-stream-money-every-second)
- [Protocol Architecture | Superfluid | Stream Money Every Second](#protocol-architecture-superfluid-stream-money-every-second)
- [Superfluid | Stream Money Every Second](#superfluid-stream-money-every-second)
- [Super Tokens | Superfluid | Stream Money Every Second](#super-tokens-superfluid-stream-money-every-second)
- [Deploy a Super Token | Superfluid | Stream Money Every Second](#deploy-a-super-token-superfluid-stream-money-every-second)
- [CFAv1Forwarder | Superfluid | Stream Money Every Second](#cfav1forwarder-superfluid-stream-money-every-second)
- [Superfluid | Stream Money Every Second](#superfluid-stream-money-every-second)
- [Superfluid | Stream Money Every Second](#superfluid-stream-money-every-second)
- [Money Streaming | Superfluid | Stream Money Every Second](#money-streaming-superfluid-stream-money-every-second)
- [Superfluid | Stream Money Every Second](#superfluid-stream-money-every-second)
- [Use Cases | Superfluid | Stream Money Every Second](#use-cases-superfluid-stream-money-every-second)
- [Advanced Topics | Superfluid | Stream Money Every Second](#advanced-topics-superfluid-stream-money-every-second)
- [Glossary of Terms | Superfluid | Stream Money Every Second](#glossary-of-terms-superfluid-stream-money-every-second)
- [Money Streaming | Superfluid | Stream Money Every Second](#money-streaming-superfluid-stream-money-every-second)
- [Money Streaming in Superfluid | Superfluid | Stream Money Every Second](#money-streaming-in-superfluid-superfluid-stream-money-every-second)
- [Super Tokens | Superfluid | Stream Money Every Second](#super-tokens-superfluid-stream-money-every-second)
- [Super Tokens | Superfluid | Stream Money Every Second](#super-tokens-superfluid-stream-money-every-second)
- [Distribution Pools | Superfluid | Stream Money Every Second](#distribution-pools-superfluid-stream-money-every-second)
- [Money Streaming | Superfluid | Stream Money Every Second](#money-streaming-superfluid-stream-money-every-second)
- [Examples | Superfluid | Stream Money Every Second](#examples-superfluid-stream-money-every-second)
- [Advanced Topics | Superfluid | Stream Money Every Second](#advanced-topics-superfluid-stream-money-every-second)
- [Advanced Topics | Superfluid | Stream Money Every Second](#advanced-topics-superfluid-stream-money-every-second)
- [Distribution Pools | Superfluid | Stream Money Every Second](#distribution-pools-superfluid-stream-money-every-second)
- [Examples | Superfluid | Stream Money Every Second](#examples-superfluid-stream-money-every-second)
- [Contribute | Superfluid | Stream Money Every Second](#contribute-superfluid-stream-money-every-second)
- [Contract Addresses | Superfluid | Stream Money Every Second](#contract-addresses-superfluid-stream-money-every-second)
- [Overview of Super Tokens | Superfluid | Stream Money Every Second](#overview-of-super-tokens-superfluid-stream-money-every-second)
- [GDAv1Forwarder | Superfluid | Stream Money Every Second](#gdav1forwarder-superfluid-stream-money-every-second)
- [Using the SuperTokenV1Library | Superfluid | Stream Money Every Second](#using-the-supertokenv1library-superfluid-stream-money-every-second)
- [SuperTokenV1Library | Superfluid | Stream Money Every Second](#supertokenv1library-superfluid-stream-money-every-second)
- [Subgraph Endpoints | Superfluid | Stream Money Every Second](#subgraph-endpoints-superfluid-stream-money-every-second)
- [ISuperfluidPool | Superfluid | Stream Money Every Second](#isuperfluidpool-superfluid-stream-money-every-second)
- [Distribution Pools Explained | Superfluid | Stream Money Every Second](#distribution-pools-explained-superfluid-stream-money-every-second)
- [ISETH | Superfluid | Stream Money Every Second](#iseth-superfluid-stream-money-every-second)
- [ISuperToken | Superfluid | Stream Money Every Second](#isupertoken-superfluid-stream-money-every-second)
- [Guides | Superfluid | Stream Money Every Second](#guides-superfluid-stream-money-every-second)
- [Guides | Superfluid | Stream Money Every Second](#guides-superfluid-stream-money-every-second)
- [Guides | Superfluid | Stream Money Every Second](#guides-superfluid-stream-money-every-second)
- [Examples | Superfluid | Stream Money Every Second](#examples-superfluid-stream-money-every-second)
- [Testing | Superfluid | Stream Money Every Second](#testing-superfluid-stream-money-every-second)
- [Create, Update and Connect your Pools | Superfluid | Stream Money Every Second](#create-update-and-connect-your-pools-superfluid-stream-money-every-second)
- [Testing | Superfluid | Stream Money Every Second](#testing-superfluid-stream-money-every-second)
- [Manage Access Control and User Data | Superfluid | Stream Money Every Second](#manage-access-control-and-user-data-superfluid-stream-money-every-second)
- [Manage Access Control and User Data | Superfluid | Stream Money Every Second](#manage-access-control-and-user-data-superfluid-stream-money-every-second)
- [Create, Update, and Delete Flows | Superfluid | Stream Money Every Second](#create-update-and-delete-flows-superfluid-stream-money-every-second)
- [Liquidations & TOGA | Superfluid | Stream Money Every Second](#liquidations-toga-superfluid-stream-money-every-second)
- [Running a Sentinel | Superfluid | Stream Money Every Second](#running-a-sentinel-superfluid-stream-money-every-second)
- [Token-Cost-Averaging | Superfluid | Stream Money Every Second](#token-cost-averaging-superfluid-stream-money-every-second)
- [Super Apps | Superfluid | Stream Money Every Second](#super-apps-superfluid-stream-money-every-second)
- [Social & Community | Superfluid | Stream Money Every Second](#social-community-superfluid-stream-money-every-second)
- [Superfluid Host | Superfluid | Stream Money Every Second](#superfluid-host-superfluid-stream-money-every-second)
- [Wrap and Unwrap Super Tokens | Superfluid | Stream Money Every Second](#wrap-and-unwrap-super-tokens-superfluid-stream-money-every-second)
- [Tracking Super Token Balances | Superfluid | Stream Money Every Second](#tracking-super-token-balances-superfluid-stream-money-every-second)
- [How to make your balance dance? | Superfluid | Stream Money Every Second](#how-to-make-your-balance-dance-superfluid-stream-money-every-second)
- [Subgraph | Superfluid | Stream Money Every Second](#subgraph-superfluid-stream-money-every-second)
- [FlowSplitter Smart Contract | Superfluid | Stream Money Every Second](#flowsplitter-smart-contract-superfluid-stream-money-every-second)
- [Super Apps | Superfluid | Stream Money Every Second](#super-apps-superfluid-stream-money-every-second)
- [Create and Manage Distribution Pools | Superfluid | Stream Money Every Second](#create-and-manage-distribution-pools-superfluid-stream-money-every-second)
- [Automations | Superfluid | Stream Money Every Second](#automations-superfluid-stream-money-every-second)
- [Advertisement Auction DApp | Superfluid | Stream Money Every Second](#advertisement-auction-dapp-superfluid-stream-money-every-second)
- [Solvency | Superfluid | Stream Money Every Second](#solvency-superfluid-stream-money-every-second)
- [Batch transactions with Macros | Superfluid | Stream Money Every Second](#batch-transactions-with-macros-superfluid-stream-money-every-second)
- [Connecting and Claiming from the Pools | Superfluid | Stream Money Every Second](#connecting-and-claiming-from-the-pools-superfluid-stream-money-every-second)
- [Staking Platform | Superfluid | Stream Money Every Second](#staking-platform-superfluid-stream-money-every-second)
- [Rewards Distribution Using Macros | Superfluid | Stream Money Every Second](#rewards-distribution-using-macros-superfluid-stream-money-every-second)
- [Bounty Program | Superfluid | Stream Money Every Second](#bounty-program-superfluid-stream-money-every-second)
- [Batch Calls with Host Contract | Superfluid | Stream Money Every Second](#batch-calls-with-host-contract-superfluid-stream-money-every-second)
- [Subgraph | Superfluid | Stream Money Every Second](#subgraph-superfluid-stream-money-every-second)
- [Security & Bug Bounties | Superfluid | Stream Money Every Second](#security-bug-bounties-superfluid-stream-money-every-second)
- [Solvency Dashboard | Superfluid | Stream Money Every Second](#solvency-dashboard-superfluid-stream-money-every-second)
- [Super Apps in Depth | Superfluid | Stream Money Every Second](#super-apps-in-depth-superfluid-stream-money-every-second)
- [Token Explorer Submission | Superfluid | Stream Money Every Second](#token-explorer-submission-superfluid-stream-money-every-second)
- [Quickstart | Superfluid | Stream Money Every Second](#quickstart-superfluid-stream-money-every-second)
- [Callbacks | Superfluid | Stream Money Every Second](#callbacks-superfluid-stream-money-every-second)
- [Registering Super Apps | Superfluid | Stream Money Every Second](#registering-super-apps-superfluid-stream-money-every-second)
- [Stream Scheduler | Superfluid | Stream Money Every Second](#stream-scheduler-superfluid-stream-money-every-second)
- [Auto-Wrap | Superfluid | Stream Money Every Second](#auto-wrap-superfluid-stream-money-every-second)
- [Vesting Scheduler | Superfluid | Stream Money Every Second](#vesting-scheduler-superfluid-stream-money-every-second)
- [Stream Accounting API | Superfluid | Stream Money Every Second](#stream-accounting-api-superfluid-stream-money-every-second)
---
# Superfluid | Stream Money Every Second | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/#__docusaurus_skipToContent_fallback)
Technical DocumentationThe Most Advanced Money Streaming Protocol
[### What is Superfluid?\
\
Learn about the core concepts of the Superfluid Protocol.](https://docs.superfluid.org/docs/concepts/superfluid)
[### Get Started\
\
Start building very quickly with Superfluid.](https://docs.superfluid.org/docs/protocol/quickstart)
[### Contracts\
\
Learn about the core concepts of the Superfluid Protocol, and how to build your smart contracts.](https://docs.superfluid.org/docs/protocol/quickstart)
[### SDK\
\
Learn about how to interact with Superfluid to build your client-side SDK.](https://docs.superfluid.org/docs/sdk/quickstart)
[### Governance\
\
Learn about the Superfluid DAO governance and tokenomics.](https://docs.superfluid.org/docs/governance)
[### Technical Reference\
\
A comprehensive reference for the most relevant Superfluid contracts.](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder)
Learn about Superfluid
----------------------
[### What is Superfluid?\
\
Learn about the core concepts of Superfluid](https://docs.superfluid.org/docs/concepts/superfluid)
[### What are Super Tokens?\
\
Understand the powerful Super Token standard](https://docs.superfluid.org/docs/concepts/overview/super-tokens)
[### What are Distribution Pools?\
\
Understand the power of Money Streaming](https://docs.superfluid.org/docs/concepts/overview/distributions)
[### Deploy your Super Token (no-code)\
\
Deploy your Wrapped or Pure Super Token](https://docs.superfluid.org/docs/category/deploy-a-super-token)
Integrate with Superfluid
-------------------------
[### Smart Contracts Quick Start\
\
Quickly integrate Superfluid in your contracts](https://docs.superfluid.org/docs/protocol/quickstart)
[### SDK Quick Start\
\
Quickly build your Superfluid SDK](https://docs.superfluid.org/docs/sdk/quickstart)
[### Integrate Streams in your contract\
\
Learn how to create, update and delete flows from your contracts](https://docs.superfluid.org/docs/protocol/money-streaming/guides/create-update-delete-flow)
[### Integrate Distribution Pools in your contracts\
\
Learn how to create and manage Pools from your contracts](https://docs.superfluid.org/docs/protocol/distributions/guides/pools)
---
# What is Superfluid? | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/concepts/superfluid#__docusaurus_skipToContent_fallback)
On this page
Introduction[](https://docs.superfluid.org/docs/concepts/superfluid#introduction "Direct link to Introduction")
-----------------------------------------------------------------------------------------------------------------
Superfluid is a revolutionary asset [streaming](https://docs.superfluid.org/docs/concepts/overview/money-streaming)
and [distribution](https://docs.superfluid.org/docs/concepts/overview/distributions)
protocol bringing subscriptions, salaries, vesting, and rewards to DAOs and crypto-native businesses worldwide. This is made possible by the protocol’s smart contract framework which introduces the [Super Token](https://docs.superfluid.org/docs/concepts/overview/super-tokens)
- an extension to the [ERC-20](https://eips.ethereum.org/EIPS/eip-20)
standard enabling the transfer of value in completely novel ways.
Super Tokens[](https://docs.superfluid.org/docs/concepts/superfluid#super-tokens "Direct link to Super Tokens")
-----------------------------------------------------------------------------------------------------------------
The Superfluid protocol is designed to be a "token-centric" protocol, in that all of its functionalities revolve around the concept of [Super Tokens](https://docs.superfluid.org/docs/concepts/overview/super-tokens)
. The framework & Super Token standard can be used to add dynamic balances to tokens on chain, describing cash flows and executing them automatically over time in a non-interactive way. Any token can be transferred in Superfluid streams or distributions, which are programmable, composable, and modular. No capital is locked up, and all inflows and outflows are netted in real-time at every block without consuming any gas. The code is fully open source, while the protocol is non-custodial and permissionless.

_A visualization of the Superfluid Protocol_
**The Superfluid Protocol has currently two main pillars that define its interactions with Super Tokens. These pillars (formerly called Agreements) are the following:**
* [_**Money Streaming**_](https://docs.superfluid.org/docs/concepts/overview/money-streaming)
- A set of features that enable the creation of money streams between two parties.
* [_**Distributions**_](https://docs.superfluid.org/docs/concepts/overview/distributions)
- A set of features that enables the creation of a pool of funds that can be distributed to multiple recipients.
We go in further details about these two pillars in the next sections.
Money Streaming[](https://docs.superfluid.org/docs/concepts/superfluid#money-streaming "Direct link to Money Streaming")
--------------------------------------------------------------------------------------------------------------------------
### Definition[](https://docs.superfluid.org/docs/concepts/superfluid#definition "Direct link to Definition")
Money Streaming is a continuous transfer of tokens from a sender to a receiver at a defined per-second rate, resulting in a "stream". This stream is perpetual and persists until it's canceled by either the sender or the receiver, or until the sender's Super Token balance is depleted.
### Explanation[](https://docs.superfluid.org/docs/concepts/superfluid#explanation "Direct link to Explanation")
Money Streaming is a novel approach to token transfers, offering a dynamic way of sending funds. Instead of one-time transactions, tokens flow from the sender to the receiver continuously, creating a stream. This method provides real-time financial transactions, enabling a more fluid movement of assets over time, reflecting real-world economic activities more closely.
### Example[](https://docs.superfluid.org/docs/concepts/superfluid#example "Direct link to Example")

_A visualization of money streaming from the [Superfluid dashboard](https://app.superfluid.finance/)
_
Consider Alice wants to pay Bob a salary of 1200 USDCx per year using Money Streaming. She sets up a stream with a flow rate of 0.038 USDCx per second. Bob's balance starts increasing every second, and Alice's decreases, ensuring a steady transfer of salary.
Distributions[](https://docs.superfluid.org/docs/concepts/superfluid#distributions "Direct link to Distributions")
--------------------------------------------------------------------------------------------------------------------
### Definition[](https://docs.superfluid.org/docs/concepts/superfluid#definition-1 "Direct link to Definition")
Distributions in Superfluid refer to a scalable one-to-many fund transfer method. It involves creating pools with a pool admin managing units for members, who can receive funds instantly or through continuous streaming.
### Explanation[](https://docs.superfluid.org/docs/concepts/superfluid#explanation-1 "Direct link to Explanation")
Distributions are a significant advancement in decentralized finance, enabling efficient and scalable fund transfers among multiple recipients. This method is especially useful for scenarios where funds need to be distributed among many parties, like dividends or rewards, ensuring equitable and automated distribution based on predefined units.
### Example[](https://docs.superfluid.org/docs/concepts/superfluid#example-1 "Direct link to Example")
Imagine a DeFi project creating a reward pool for liquidity providers. The project sets up a distribution pool with a total of 1000 units. If a liquidity provider has 100 units, they receive 10% of the total funds distributed through the pool, either instantly or as a continuous stream, depending on the distribution method.
* [Introduction](https://docs.superfluid.org/docs/concepts/superfluid#introduction)
* [Super Tokens](https://docs.superfluid.org/docs/concepts/superfluid#super-tokens)
* [Money Streaming](https://docs.superfluid.org/docs/concepts/superfluid#money-streaming)
* [Definition](https://docs.superfluid.org/docs/concepts/superfluid#definition)
* [Explanation](https://docs.superfluid.org/docs/concepts/superfluid#explanation)
* [Example](https://docs.superfluid.org/docs/concepts/superfluid#example)
* [Distributions](https://docs.superfluid.org/docs/concepts/superfluid#distributions)
* [Definition](https://docs.superfluid.org/docs/concepts/superfluid#definition-1)
* [Explanation](https://docs.superfluid.org/docs/concepts/superfluid#explanation-1)
* [Example](https://docs.superfluid.org/docs/concepts/superfluid#example-1)
---
# Quickstart | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/sdk/quickstart#__docusaurus_skipToContent_fallback)
On this page
This guide will help you get started with the Superfluid protocol by creating a simple React app that interacts with the protocol. You'll learn how to connect your wallet, create streams, and create pools using the Superfluid protocol.
How to Interact with the Superfluid Protocol[](https://docs.superfluid.org/docs/sdk/quickstart#how-to-interact-with-the-superfluid-protocol "Direct link to How to Interact with the Superfluid Protocol")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
When interacting with the Superfluid protocol from a client application, you'll use one of two contracts depending on the functionality you need:
1. For Money Streaming: Use the [`CFAv1Forwarder`](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder)
contract
2. For Distribution Pools: Use the [`GDAv1Forwarder`](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder)
contract
We use these forwarder contracts instead of building an SDK because:
* It simplifies the integration process
* It reduces the need for frequent updates to the SDK
* It allows for more flexibility and direct interaction with the protocol
Contract Addresses and ABIs[](https://docs.superfluid.org/docs/sdk/quickstart#contract-addresses-and-abis "Direct link to Contract Addresses and ABIs")
---------------------------------------------------------------------------------------------------------------------------------------------------------
Here are the addresses for each contract across all Superfluid-supported chains:
* `CFAv1Forwarder`: `0xcfA132E353cB4E398080B9700609bb008eceB125`
* `GDAv1Forwarder`: `0x6DA13Bde224A05a288748d857b9e7DDEffd1dE08`
You can find the full ABIs for these contracts in the following technical references:
* [CFAv1Forwarder ABI](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder)
* [GDAv1Forwarder ABI](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder)
Creating a React App (Next.js)[](https://docs.superfluid.org/docs/sdk/quickstart#creating-a-react-app-nextjs "Direct link to Creating a React App (Next.js)")
---------------------------------------------------------------------------------------------------------------------------------------------------------------
To create a new Next.js app, follow these steps:
1. Open your terminal and run:
npx create-next-app@latest my-superfluid-app
2. Navigate to your new app directory:
cd my-superfluid-app
3. Install necessary dependencies:
npm install ethers@5.7.2
Superfluid Interaction Component[](https://docs.superfluid.org/docs/sdk/quickstart#superfluid-interaction-component "Direct link to Superfluid Interaction Component")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
In this section, we will provide a React component that allows you to interact with the Superfluid protocol. This component will allow you to:
* Connect your wallet (eg. Metamask)
* Create a stream through the `CFAv1Forwarder` contract (for [Money Streaming](https://docs.superfluid.org/docs/sdk/docs/concepts/overview/money-streaming)
)
* Create a pool through the `GDAv1Forwarder` contract (for [Distribution Pools](https://docs.superfluid.org/docs/sdk/docs/concepts/overview/distributions)
)
Here's a React component that allows you to create a stream and create a pool. You can copy and paste this into a new file in your Next.js app's `pages` directory (e.g., `pages/superfluid-demo.js`):
note
For a full list of available functions and events, refer to the [CFAv1Forwarder technical reference](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder)
and [GDAv1Forwarder technical reference](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder)
.
Live Editor
// Don't forget imports
//import React, { useState } from 'react';
//import { ethers } from 'ethers';
function SuperfluidDemo() {
const \[provider, setProvider\] \= useState(null); const \[account, setAccount\] \= useState(''); const \[tokenAddress, setTokenAddress\] \= useState(''); const \[receiverAddress, setReceiverAddress\] \= useState(''); const \[flowRate, setFlowRate\] \= useState(''); const \[adminAddress, setAdminAddress\] \= useState(''); const \[message, setMessage\] \= useState('');
const CFAv1ForwarderAddress \= '0xcfA132E353cB4E398080B9700609bb008eceB125'; const GDAv1ForwarderAddress \= '0x6DA13Bde224A05a288748d857b9e7DDEffd1dE08'; // Simplified ABIs with only the functions we need const CFAv1ForwarderABI \= \[ "function createFlow(address token, address sender, address receiver, int96 flowRate, bytes memory userData) external returns (bool)" \];
const GDAv1ForwarderABI \= \[ "function createPool(address token, address admin, (uint32 transferabilityForUnitsOwner, bool distributionFromAnyAddress) memory poolConfig) external returns (bool, address)" \];
const connectWallet \= async () \=> { if (typeof window.ethereum !== 'undefined') { try { await window.ethereum.request({ method: 'eth\_requestAccounts' }); const provider \= new ethers.providers.Web3Provider(window.ethereum); setProvider(provider); const signer \= provider.getSigner(); const address \= await signer.getAddress(); setAccount(address); setMessage(\`Connected to ${address}\`); } catch (error) { console.error('Failed to connect wallet:', error); setMessage('Failed to connect wallet. Please try again.'); } } else { setMessage('Please install Metamask to use this feature.'); } };
const createStream \= async () \=> { if (!provider) { setMessage('Please connect your wallet first.'); return; }
const signer \= provider.getSigner(); const contract \= new ethers.Contract(CFAv1ForwarderAddress, CFAv1ForwarderABI, signer);
try { const tx \= await contract.createFlow( tokenAddress, account, receiverAddress, flowRate, "0x" ); await tx.wait(); setMessage('The stream has been created successfully.'); } catch (error) { console.error('Error creating stream:', error); setMessage('Failed to create stream. Please try again.'); } };
const createPool \= async () \=> { if (!provider) { setMessage('Please connect your wallet first.'); return; }
const signer \= provider.getSigner(); const contract \= new ethers.Contract(GDAv1ForwarderAddress, GDAv1ForwarderABI, signer);
try { const poolConfig \= { transferabilityForUnitsOwner: 0, distributionFromAnyAddress: false }; const tx \= await contract.createPool(tokenAddress, adminAddress, poolConfig); const receipt \= await tx.wait(); const \[success, poolAddress\] \= receipt.events.find(e \=> e.event \=== 'PoolCreated').args; setMessage(\`Pool created successfully at ${poolAddress}\`); } catch (error) { console.error('Error creating pool:', error); setMessage('Failed to create pool. Please try again.'); } };
return (
);
}
Result
Loading...
To use this component:
1. Copy the above code into a new file in your Next.js app's `pages` directory (e.g., `pages/superfluid-demo.js`).
2. Uncomment the necessary imports at the top of the file.
3. Run your Next.js app with `npm run dev`.
4. Navigate to `http://localhost:3000/superfluid-demo` in your browser.
5. Connect your wallet, then you can create streams and pools using the Superfluid protocol.
This component provides a basic interface for creating streams and pools. In a production environment, you would want to add more error checking, input validation, and additional features.
About the Component
A few tips in order to make sure you can use the component correctly:
* The component above uses simple ethers.js functions to interact with the Superfluid protocol. You can choose to use a different library or SDK if you prefer (eg. [Viem](https://viem.sh/)
, [Web3.js](https://docs.web3js.org/)
).
* The component does not manage wallet connections or chain switching in a production-ready way. You should add more robust error handling and user feedback.
* The component uses the Superfluid forwarders ABIs in a simplified form. You can find the full ABIs in the [CFAv1Forwarder technical reference](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder)
and [GDAv1Forwarder technical reference](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder)
.
* [How to Interact with the Superfluid Protocol](https://docs.superfluid.org/docs/sdk/quickstart#how-to-interact-with-the-superfluid-protocol)
* [Contract Addresses and ABIs](https://docs.superfluid.org/docs/sdk/quickstart#contract-addresses-and-abis)
* [Creating a React App (Next.js)](https://docs.superfluid.org/docs/sdk/quickstart#creating-a-react-app-nextjs)
* [Superfluid Interaction Component](https://docs.superfluid.org/docs/sdk/quickstart#superfluid-interaction-component)
---
# Quickstart | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/protocol/quickstart#__docusaurus_skipToContent_fallback)
On this page
Superfluid is a token-centric protocol revolving around a new token standard called Super Token. Super Tokens have special capabilities. One of them allows to create second-by-second token transfers (called [Money Streaming](https://docs.superfluid.org/docs/protocol/money-streaming/overview)
). In this guide, we'll walk through the process of setting up and deploying a basic vesting contract which deploys a Mock Super Token and creates a stream to a recipient.
This contract allows you to:
* Deploy a Mock Super Token
* Create, update or delete money streams
Why this Quickstart?
This is just an example to get you started with Superfluid. You can use this as a base to build more complex applications.
You DO NOT need to follow this quickstart guide in order to create, update and delete streams. You can do this directly from the [Dashboard](https://app.superfluid.finance/)
or by interacting with the [CFAv1Forwarder contract](https://docs.superfluid.finance/docs/technical-reference/CFAv1Forwarder)
.
Prerequisites[](https://docs.superfluid.org/docs/protocol/quickstart#prerequisites "Direct link to Prerequisites")
--------------------------------------------------------------------------------------------------------------------
* The [Superfluid Simple Vesting Contract Repository](https://github.com/superfluid-finance/superfluid-boilerplate)
* A development environment _(Remix or Foundry)_
* A testnet wallet (in case you want to deploy the contract to a testnet) _(e.g., MetaMask)_
Contract Overview: SuperfluidBoilerplate[](https://docs.superfluid.org/docs/protocol/quickstart#contract-overview-superfluidboilerplate "Direct link to Contract Overview: SuperfluidBoilerplate")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
In this guide we will describe the contract [`SuperfluidVesting.sol`](https://github.com/superfluid-finance/superfluid-quickstart/blob/master/src/SuperfluidVesting.sol)
:
* This contract is designed to interact with the Superfluid protocol, specifically to deploy a [Super Token](https://docs.superfluid.org/docs/protocol/super-tokens/overview)
and use [Money Streaming](https://docs.superfluid.org/docs/protocol/money-streaming/overview)
.
* The contract enables the deployment of a Mock Super Token in the constructor.
* This contract enables the creation, modification, and deletion of continuous money streams to the a recipient.
_Visualization showing the vesting contract streaming tokens to users_
### Contract and Key Functions[](https://docs.superfluid.org/docs/protocol/quickstart#contract-and-key-functions "Direct link to Contract and Key Functions")
Click here to show `SuperfluidBoilerplate` contract
// SPDX-License-Identifier: UNLICENSEDpragma solidity ^0.8.13;import {SuperTokenV1Library, ISuperToken, ISuperfluid} from "@superfluid-finance/ethereum-contracts/contracts/apps/SuperTokenV1Library.sol";import {ISuperTokenFactory} from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperTokenFactory.sol";import {PureSuperTokenProxy, IPureSuperToken} from "./PureSuperToken.sol";/// @title SuperfluidVesting/// @notice A contract for managing token vesting using Superfluid streams/// @dev Uses SuperTokenV1Library for handling Superfluid token operationscontract SuperfluidVesting { using SuperTokenV1Library for ISuperToken; /// @notice The Super Token that will be used for vesting ISuperToken public acceptedSuperToken; /// @notice The Superfluid protocol host contract ISuperfluid public host; /// @notice The address of the contract owner address public owner; /// @notice Restricts function access to contract owner modifier onlyOwner() { require(msg.sender == owner, "Only owner can call this function"); _; } /// @notice Initializes the vesting contract /// @param _host The address of the Superfluid host contract /// @dev Assigns the host and owner addresses /// Creates a new PureSuperToken and initializes it with mock data /// Mints the total supply of the token to the contract constructor(ISuperfluid _host) { host = _host; owner = msg.sender; acceptedSuperToken = IPureSuperToken(address(new PureSuperTokenProxy())); PureSuperTokenProxy(payable(address(acceptedSuperToken))).initialize( ISuperTokenFactory(host.getSuperTokenFactory()), "Mock Super Token", "mST", address(this), 1000000000000000000000000 ); } /// @notice Creates or updates a vesting stream for a recipient /// @param recipient The address that will receive the stream /// @param flowRate The rate at which tokens will be streamed (tokens per second) /// @dev Flow rate must be positive and contract must have sufficient balance function setVesting(address recipient, int96 flowRate) public onlyOwner { require(flowRate > 0, "Flow rate must be greater than 0"); require(acceptedSuperToken.balanceOf(address(this)) > 0, "Insufficient balance"); acceptedSuperToken.flow(recipient, flowRate); }}
The contract has two main methods:
* **constructor**: Creates a new contract and with it it deploys a Mock Super Token with 1,000,000 units initial supply minted to the contract.
* **setVesting**: Creates, updates or deletes a stream to the user with the specified flow rate, gated by the modifier `onlyOwner`.
Environment Setup and Deployment[](https://docs.superfluid.org/docs/protocol/quickstart#environment-setup-and-deployment "Direct link to Environment Setup and Deployment")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* Remix IDE
* Foundry
### Using Remix IDE[](https://docs.superfluid.org/docs/protocol/quickstart#using-remix-ide "Direct link to Using Remix IDE")
1. **Create Files**:
* Create `SuperfluidVesting.sol` and paste the main contract from the [repository's `/src` folder](https://github.com/superfluid-finance/superfluid-quickstart/tree/master/src)
* Create `PureSuperToken.sol` and paste the interface from the [repository's `/src` folder](https://github.com/superfluid-finance/superfluid-quickstart/tree/master/src)
2. **Compile**: Select compiler version 0.8.20 or higher
3. **Deploy**:
* Select "Injected Provider - MetaMask"
* Choose your network (make sure Superfluid supports it - check [here](https://explorer.superfluid.finance/base-mainnet/protocol)
)
* Enter the Superfluid host address in the constructor (get it from the [docs](https://docs.superfluid.org/docs/protocol/contract-addresses)
or from the [explorer](https://explorer.superfluid.finance/base-mainnet/protocol)
)
* Click "Deploy"
### Using Foundry[](https://docs.superfluid.org/docs/protocol/quickstart#using-foundry "Direct link to Using Foundry")
After cloning the [Superfluid Boilerplate Repository](https://github.com/superfluid-finance/superfluid-quickstart)
, you can test and deploy the contract with the following commands:
1. **Install Dependencies**:
forge install
2. **Test**:
forge test
3. **Deploy**:
forge create src/SuperfluidVesting.sol:SuperfluidVesting \ --constructor-args SUPERFLUID_HOST_ADDRESS \ --rpc-url YOUR_RPC_URL \ --private-key YOUR_PRIVATE_KEY
Where can I get the Superfluid host address?
Make sure to use the correct Superfluid host address for your network. You can get the Superfluid host address from the [docs](https://docs.superfluid.org/docs/protocol/contract-addresses)
or from the [explorer](https://explorer.superfluid.finance/base-mainnet/protocol)
.
Using the Contract[](https://docs.superfluid.org/docs/protocol/quickstart#using-the-contract "Direct link to Using the Contract")
-----------------------------------------------------------------------------------------------------------------------------------
After deployment, interact with your contract in 3 different ways:
1. **Create Vesting**:
* Call `setFlowRate(flowRate)`
* The `flowRate` is tokens per second (with 18 decimals)
* Example:
* For 1 token per month, use `flowRate ≈ 380414535736`
2. **Update Vesting**:
* Call `setFlowRate(flowRate)`
* The `flowRate` is tokens per second (with 18 decimals)
* Example:
* For 1 token per week, use `flowRate ≈ 1653439153439`
3. **Delete Vesting**:
* Call `setFlowRate(0)`
How do I find the full list of methods for the SuperTokenV1Library?
You can find the full list of methods for the SuperTokenV1Library in the [SuperTokenV1Library Technical Reference](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library)
.
Testing Your Contract[](https://docs.superfluid.org/docs/protocol/quickstart#testing-your-contract "Direct link to Testing Your Contract")
--------------------------------------------------------------------------------------------------------------------------------------------
As you can see in the repository, we have a test file that tests the contract. Here's a breakdown of the test file:
// SPDX-License-Identifier: MIT OR Apache-2.0pragma solidity ^0.8.13;import "forge-std/Test.sol";import {SuperfluidVesting} from "../src/SuperfluidVesting.sol";import {SuperfluidFrameworkDeployer} from "@superfluid-finance/ethereum-contracts/contracts/utils/SuperfluidFrameworkDeployer.t.sol";import {SuperTokenV1Library, ISuperToken, ISuperfluid} from "@superfluid-finance/ethereum-contracts/contracts/apps/SuperTokenV1Library.sol";import { ERC1820RegistryCompiled } from "@superfluid-finance/ethereum-contracts/contracts/libs/ERC1820RegistryCompiled.sol";contract SuperfluidVestingTest is Test { SuperfluidVesting private vestingContract; SuperfluidFrameworkDeployer.Framework private sf; ISuperToken private acceptedSuperToken; using SuperTokenV1Library for ISuperToken; function setUp() public { vm.etch(ERC1820RegistryCompiled.at, ERC1820RegistryCompiled.bin); SuperfluidFrameworkDeployer sfDeployer = new SuperfluidFrameworkDeployer(); sfDeployer.deployTestFramework(); sf = sfDeployer.getFramework(); vestingContract = new SuperfluidVesting(sf.host); acceptedSuperToken = vestingContract.acceptedSuperToken(); } function testVesting() public { vestingContract.setVesting(address(this), 100000000); uint256 flowRate = uint256(uint96(acceptedSuperToken.getFlowRate(address(vestingContract), address(this)))); assertEq(flowRate, uint256(100000000)); }}
The test file does two main things:
1. **Setup (`setUp` function)**:
* Deploys a local version of the Superfluid protocol for testing
* Creates our `SuperfluidBoilerplate` contract
* Deploys the Mock Super Token
2. **Vesting Test (`testVesting` function)**:
* Creates a vesting stream with a flow rate of 100000000 wad/second
* Verifies that the flow rate was set correctly
You can run these tests using the `forge test` command as shown in the setup instructions above.
Next Steps[](https://docs.superfluid.org/docs/protocol/quickstart#next-steps "Direct link to Next Steps")
-----------------------------------------------------------------------------------------------------------
Now that you understand the basics, you can:
1. **Explore Super Tokens**:
* [Super Tokens Overview](https://docs.superfluid.org/docs/protocol/super-tokens/overview)
* [Advanced Token Creation](https://docs.superfluid.org/docs/protocol/docs/protocol/super-tokens/guides/deploy-super-token/deploy-custom-super-token)
2. **Build Smart Contracts**:
* [Money Streaming Overview](https://docs.superfluid.org/docs/protocol/money-streaming/overview)
* [Distribution Pools Overview](https://docs.superfluid.org/docs/protocol/docs/protocol/distributions/overview)
* [How to use the SuperTokenV1Library](https://docs.superfluid.org/docs/protocol/super-tokens/guides/using-library)
3. **Build your client application**:
* [SDK Quickstart](https://docs.superfluid.org/docs/sdk/quickstart)
* [Prerequisites](https://docs.superfluid.org/docs/protocol/quickstart#prerequisites)
* [Contract Overview: SuperfluidBoilerplate](https://docs.superfluid.org/docs/protocol/quickstart#contract-overview-superfluidboilerplate)
* [Contract and Key Functions](https://docs.superfluid.org/docs/protocol/quickstart#contract-and-key-functions)
* [Environment Setup and Deployment](https://docs.superfluid.org/docs/protocol/quickstart#environment-setup-and-deployment)
* [Using Remix IDE](https://docs.superfluid.org/docs/protocol/quickstart#using-remix-ide)
* [Using Foundry](https://docs.superfluid.org/docs/protocol/quickstart#using-foundry)
* [Using the Contract](https://docs.superfluid.org/docs/protocol/quickstart#using-the-contract)
* [Testing Your Contract](https://docs.superfluid.org/docs/protocol/quickstart#testing-your-contract)
* [Next Steps](https://docs.superfluid.org/docs/protocol/quickstart#next-steps)
---
# Governance Overview | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/governance#__docusaurus_skipToContent_fallback)
The Superfluid protocol is governed by its community through a decentralized autonomous organization (DAO). This section outlines the key components of Superfluid's governance system.
[### Organization\
\
Learn about the Superfluid DAO structure, Foundation, Security Council, and governance bodies.](https://forum.superfluid.org/t/superfluid-dao-governance-and-tokenomics/69#p-124-organization-2)
[### Voting Process\
\
Understand how proposals are submitted, voted on, and implemented through the Superfluid governance system.](https://forum.superfluid.org/t/superfluid-dao-governance-and-tokenomics/69#p-124-voting-3)
[### SUP Token\
\
Explore the Superfluid Token (SUP), its functionality, distribution, and role in protocol governance.](https://forum.superfluid.org/t/superfluid-dao-governance-and-tokenomics/69#p-124-sup-token-4)
[### Streaming Programmatic Rewards\
\
Discover how the DAO allocates tokens to users and developers to incentivize ecosystem growth.](https://forum.superfluid.org/t/superfluid-dao-governance-and-tokenomics/69#p-124-streaming-programmatic-rewards-8)
info
For detailed information about specific aspects of governance, click on any of the cards above.
---
# Protocol Architecture | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/technical-reference/Architecture#__docusaurus_skipToContent_fallback)
On this page
The Superfluid Protocol is designed with a modular and upgradable architecture, consisting of several smart contract components that interact with each other to facilitate real-time finance on the blockchain.
Overview[](https://docs.superfluid.org/docs/technical-reference/Architecture#overview "Direct link to Overview")
------------------------------------------------------------------------------------------------------------------
The architecture diagram below provides a high-level overview of the Superfluid Protocol's components and their relationships. It is the protocol deployed when a new `SuperfluidFrameworkDeployer` instance is created and the method `deployFramework()`.

_Architecture of the Superfluid Protocol_
Legend[](https://docs.superfluid.org/docs/technical-reference/Architecture#legend "Direct link to Legend")
------------------------------------------------------------------------------------------------------------
* **Immutable Instance**: These are contract instances that are not intended to be upgraded or changed.
* **Upgradable Instance**: These are contract instances that are intended to be upgraded or changed, eventually by the Superfluid Protocol's Governance.
* **Link**: Represents the relationship or interaction between components.
Components[](https://docs.superfluid.org/docs/technical-reference/Architecture#components "Direct link to Components")
------------------------------------------------------------------------------------------------------------------------
### SuperToken (UUPS Proxy - EIP-1967)[](https://docs.superfluid.org/docs/technical-reference/Architecture#supertoken-uups-proxy---eip-1967 "Direct link to SuperToken (UUPS Proxy - EIP-1967)")
This is the fundamental smart contract within the Superfluid Protocol, which is an upgradable advanced token contract which inherits from the ERC20 standard, and enhances it with additional features such as Money Streaming and Distributions.
Unmanaged SuperTokens
Super Token contracts can be created by anyone, and can either be managed by the Superfluid Protocol ([The Host](https://docs.superfluid.org/docs/technical-reference/Architecture#superfluid-host-contract-uups-proxy)
), or completely unmanaged with no influence from the Host. They can be used to represent any asset or right, and can be used in any context.
### Superfluid Agreements[](https://docs.superfluid.org/docs/technical-reference/Architecture#superfluid-agreements "Direct link to Superfluid Agreements")
#### ConstantFlowAgreementV1 (UUPS Proxy)[](https://docs.superfluid.org/docs/technical-reference/Architecture#constantflowagreementv1-uups-proxy "Direct link to ConstantFlowAgreementV1 (UUPS Proxy)")
A versioned agreement that governs the continuous flow of tokens between parties, ie [Money Streaming](https://docs.superfluid.org/docs/protocol/money-streaming/overview)
.
#### InstantDistributionAgreementV1 (UUPS Proxy)[](https://docs.superfluid.org/docs/technical-reference/Architecture#instantdistributionagreementv1-uups-proxy "Direct link to InstantDistributionAgreementV1 (UUPS Proxy)")
A smart contract that manages the mechanisms for the instant distribution of tokens, a feature that allows for scalable one-to-many token distributions.
Deprecated
This agreement is in the process of being deprecated in favor of the more flexible [GeneralDistributionAgreementV1](https://docs.superfluid.org/docs/technical-reference/Architecture#generaldistributionagreementv1-uups-proxy)
.
#### GeneralDistributionAgreementV1 (UUPS Proxy)[](https://docs.superfluid.org/docs/technical-reference/Architecture#generaldistributionagreementv1-uups-proxy "Direct link to GeneralDistributionAgreementV1 (UUPS Proxy)")
A smart contract that manages the mechanisms for everything related to one-to-many transfers and streams, ie [Distributions](https://docs.superfluid.org/docs/protocol/distributions/overview)
.
### Infrastructure[](https://docs.superfluid.org/docs/technical-reference/Architecture#infrastructure "Direct link to Infrastructure")
#### Superfluid Host Contract (UUPS Proxy)[](https://docs.superfluid.org/docs/technical-reference/Architecture#superfluid-host-contract-uups-proxy "Direct link to Superfluid Host Contract (UUPS Proxy)")
The central contract that hosts the Superfluid Protocol, managing the various tokens and agreements.
#### SuperTokenFactory (UUPS Proxy)[](https://docs.superfluid.org/docs/technical-reference/Architecture#supertokenfactory-uups-proxy "Direct link to SuperTokenFactory (UUPS Proxy)")
A factory contract for creating SuperTokens, likely with specific initial conditions or properties.
#### SuperfluidPool (UUPS Proxy)[](https://docs.superfluid.org/docs/technical-reference/Architecture#superfluidpool-uups-proxy "Direct link to SuperfluidPool (UUPS Proxy)")
This a contract representing the [Pools](https://docs.superfluid.org/docs/protocol/distributions/guides/pools)
created to manage Distributions.
### Superfluid Governance[](https://docs.superfluid.org/docs/technical-reference/Architecture#superfluid-governance "Direct link to Superfluid Governance")
#### SuperfluidGovernanceII (UUPS Proxy)[](https://docs.superfluid.org/docs/technical-reference/Architecture#superfluidgovernanceii-uups-proxy "Direct link to SuperfluidGovernanceII (UUPS Proxy)")
The main governance contract that will allow Superfluid community members to participate in the governance of the protocol.
### Existential NFTs[](https://docs.superfluid.org/docs/technical-reference/Architecture#existential-nfts "Direct link to Existential NFTs")
#### ConstantFlowNFT (UUPS Proxy)[](https://docs.superfluid.org/docs/technical-reference/Architecture#constantflownft-uups-proxy "Direct link to ConstantFlowNFT (UUPS Proxy)")
Smart contract for non-fungible tokens (NFTs) that have a constant flow rate associated with them. These are NFTs minted to represent Money Streaming flows.
#### PoolAdminNFT (UUPS Proxy)[](https://docs.superfluid.org/docs/technical-reference/Architecture#pooladminnft-uups-proxy "Direct link to PoolAdminNFT (UUPS Proxy)")
NFT contract representing admin rights over a [SuperfluidPool](https://docs.superfluid.org/docs/technical-reference/Architecture#superfluidpool-uups-proxy)
.
#### PoolMemberNFT (UUPS Proxy)[](https://docs.superfluid.org/docs/technical-reference/Architecture#poolmembernft-uups-proxy "Direct link to PoolMemberNFT (UUPS Proxy)")
This is an NFT contract where tokens represent membership within a pool, granting units to members in that pool.
Learn more[](https://docs.superfluid.org/docs/technical-reference/Architecture#learn-more "Direct link to Learn more")
------------------------------------------------------------------------------------------------------------------------
The technical details and contract interactions are further documented in the codebase. Refer to the following for an in-depth understanding:
* [Superfluid Framework Deployment Steps](https://github.com/superfluid-finance/protocol-monorepo/blob/dev/packages/ethereum-contracts/contracts/utils/SuperfluidFrameworkDeploymentSteps.sol)
.
* [Superfluid Protocol Monorepo Wiki](https://github.com/superfluid-finance/protocol-monorepo/wiki)
.
* [Overview](https://docs.superfluid.org/docs/technical-reference/Architecture#overview)
* [Legend](https://docs.superfluid.org/docs/technical-reference/Architecture#legend)
* [Components](https://docs.superfluid.org/docs/technical-reference/Architecture#components)
* [SuperToken (UUPS Proxy - EIP-1967)](https://docs.superfluid.org/docs/technical-reference/Architecture#supertoken-uups-proxy---eip-1967)
* [Superfluid Agreements](https://docs.superfluid.org/docs/technical-reference/Architecture#superfluid-agreements)
* [Infrastructure](https://docs.superfluid.org/docs/technical-reference/Architecture#infrastructure)
* [Superfluid Governance](https://docs.superfluid.org/docs/technical-reference/Architecture#superfluid-governance)
* [Existential NFTs](https://docs.superfluid.org/docs/technical-reference/Architecture#existential-nfts)
* [Learn more](https://docs.superfluid.org/docs/technical-reference/Architecture#learn-more)
---
# Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/concepts/overview/distributions#__docusaurus_skipToContent_fallback)
On this page
The introduction of Distributions marks a significant advancement in DeFi applications, offering a scalable method for one-to-many fund transfers. Distributions allow for the transfer of value to multiple recipients with minimal on-chain data modification, making them infinitely scalable, highly efficient and gas-friendly.
note
There are other on-chain solutions that may seem to solve this problem without using a new token implementation (e.g [Disperse App](https://disperse.app/)
). While these solutions can be great for a low amount of recipients, they are not infinitely scalable and can become very expensive as the number of recipients increases. Furthermore, they do not allow for distributing money streaming
Overview[](https://docs.superfluid.org/docs/concepts/overview/distributions#overview "Direct link to Overview")
-----------------------------------------------------------------------------------------------------------------
Distributions function by allowing for the creation of **pools** with a designated **pool admin** who manages **units** for **pool members**. Members of these pools can receive funds either instantly or through continuous streaming, making this method highly efficient and scalable. There are two types of Distributions:
* **Instant Distributions**: They allow one transaction distribution to any number of receivers with a fixed gas cost.
* **Streaming Distributions**: They allow for continuous distribution of funds to receivers through [Money Streaming](https://docs.superfluid.org/docs/concepts/overview/money-streaming)
to a Pool.
* * *
* Instant Distribution
* Streaming Distribution
**Instant Distributions** allow one transaction to distribute to any number of receivers with a fixed gas cost.
_Click on the Blue Circle to initiate an Instant Distribution_
_By creating a Distribution Pool, you can distribute any token instantly_
**Instant Distributions** allow for continuous distribution of funds to receivers through [Money Streaming](https://docs.superfluid.org/docs/concepts/overview/money-streaming)
to a Pool.
_Watch how the continuous stream gets distributed automatically through the pool_
_By creating a Distribution Pool, you can distribute any stream with no gas cost_
* * *
### Definitions[](https://docs.superfluid.org/docs/concepts/overview/distributions#definitions "Direct link to Definitions")
* **Pool**: A channel for proportional token distribution.
* **Distribution**: The action of allocating specified token amounts to receivers.
* **Units**: Represent the proportion of the distribution each subscriber receives.
* **Pool Admin**: The administrator of the distribution process.
* **Subscribers/Pool Member**: Receivers allocated units and eligible to receive tokens through the Index.
### Key Features[](https://docs.superfluid.org/docs/concepts/overview/distributions#key-features "Direct link to Key Features")
* **Pools as Contracts**: Unlike previous approaches, pools in streaming distributions are contracts and can be ERC20 tokens. This allows pool members to transfer units among themselves, which wasn't possible earlier.
* **Roles and Permissions**: A pool admin can grant and revoke units, while any account can act as a **distributor** to execute fund distributions.
* **Distribution Methods**: There are two primary ways to distribute funds:
* **Instant Distribution**: Calculated as `distributionAmount * (poolMemberUnits / poolTotalUnits)`.
* **Streaming Distribution**: Determined by `poolFlowRate * (poolMemberUnits / poolTotalUnits)`.
* **Gas Efficiency**: The cost of executing distributions remains constant, regardless of the number of pool members.
### High-Level Workflow[](https://docs.superfluid.org/docs/concepts/overview/distributions#high-level-workflow "Direct link to High-Level Workflow")
1. **Pool Creation**: Any account can create a pool and appoint a pool admin. This pool acts as a channel for distributing funds.
2. **Unit Management**: The pool admin assigns units to members, representing their share in future distributions.
3. **Member Connection**: Pool members can connect to or disconnect from the pool, affecting how they access distributed funds.
4. **Distribution Execution**: Distributors can initiate either instant or streaming distributions, which are then divided among pool members based on their unit share.
Distribution Examples[](https://docs.superfluid.org/docs/concepts/overview/distributions#distribution-examples "Direct link to Distribution Examples")
--------------------------------------------------------------------------------------------------------------------------------------------------------
### Streaming Distribution Illustration[](https://docs.superfluid.org/docs/concepts/overview/distributions#streaming-distribution-illustration "Direct link to Streaming Distribution Illustration")
This diagram shows a distributor streaming funds to various pool members, each holding different unit amounts. Note: A single transaction can cater to multiple members.

### Adjusting Unit Counts[](https://docs.superfluid.org/docs/concepts/overview/distributions#adjusting-unit-counts "Direct link to Adjusting Unit Counts")
Here, a distributor modifies unit counts for members. This change instantly alters the distribution rate for all members in one transaction. Batch updates can be done using Superfluid's batch call.

### Modifying the Flow Rate[](https://docs.superfluid.org/docs/concepts/overview/distributions#modifying-the-flow-rate "Direct link to Modifying the Flow Rate")
This example demonstrates how a change in the distributor's streaming rate affects the total flow rate of the pool, thus instantly impacting each member's rate.

Advanced Pool Features[](https://docs.superfluid.org/docs/concepts/overview/distributions#advanced-pool-features "Direct link to Advanced Pool Features")
-----------------------------------------------------------------------------------------------------------------------------------------------------------
As pools are also ERC20 tokens, they enable:
* **Transfer of Units**: Pool members can freely transfer their units.
* **Delegated Transfers**: Using the `approve` and `transferFrom` functions, units can be transferred on behalf of a member.
These features add composability and flexibility, expanding the potential use cases for pools in web3.
* [Overview](https://docs.superfluid.org/docs/concepts/overview/distributions#overview)
* [Definitions](https://docs.superfluid.org/docs/concepts/overview/distributions#definitions)
* [Key Features](https://docs.superfluid.org/docs/concepts/overview/distributions#key-features)
* [High-Level Workflow](https://docs.superfluid.org/docs/concepts/overview/distributions#high-level-workflow)
* [Distribution Examples](https://docs.superfluid.org/docs/concepts/overview/distributions#distribution-examples)
* [Streaming Distribution Illustration](https://docs.superfluid.org/docs/concepts/overview/distributions#streaming-distribution-illustration)
* [Adjusting Unit Counts](https://docs.superfluid.org/docs/concepts/overview/distributions#adjusting-unit-counts)
* [Modifying the Flow Rate](https://docs.superfluid.org/docs/concepts/overview/distributions#modifying-the-flow-rate)
* [Advanced Pool Features](https://docs.superfluid.org/docs/concepts/overview/distributions#advanced-pool-features)
---
# Super Tokens | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/concepts/overview/super-tokens#__docusaurus_skipToContent_fallback)
On this page
Super Tokens extend the [ERC20 token standard](https://ethereum.org/en/developers/docs/standards/tokens/erc-20/)
with additional functionalities like [Money Streaming](https://docs.superfluid.org/docs/concepts/overview/money-streaming)
or [Distributions](https://docs.superfluid.org/docs/concepts/overview/distributions)
, formerly known as Super Agreements. There are two types of Super Tokens: wrapper and custom.
info
Super Tokens can perform all the functions of a traditional [ERC20 token](https://ethereum.org/en/developers/docs/standards/tokens/erc-20/)
, plus additional value transfer methods enabled by Superfluid, such as money streaming.
Wrapper Super Tokens[](https://docs.superfluid.org/docs/concepts/overview/super-tokens#wrapper-super-tokens "Direct link to Wrapper Super Tokens")
----------------------------------------------------------------------------------------------------------------------------------------------------
Wrapper Super Tokens are existing tokens wrapped to gain Superfluid functionalities. Wrapping converts the underlying token into its Super Token version, while unwrapping reverses the process.
Drag the tokens together to create a SUPER TOKEN!Your TokenWrapper Super TokenYour token is normal
_By wrapping the original token you obtain a SUPER TOKEN_
For more informations, about the wrapping process, please refer to our [Developers Section](https://docs.superfluid.org/docs/category/deploy-a-super-token)
.
Pure Super Tokens[](https://docs.superfluid.org/docs/concepts/overview/super-tokens#pure-super-tokens "Direct link to Pure Super Tokens")
-------------------------------------------------------------------------------------------------------------------------------------------
Pure Super Tokens are natively Superfluid-enabled without an underlying token. They offer inherent ERC20 functionalities plus Superfluid's Super Agreement capabilities.
Click as quickly as possible on the Pure Super Token to create your first stream!Pure Super Token
_A Pure Super Token has inherent superpowers such as [Money Streaming](https://docs.superfluid.org/docs/concepts/overview/money-streaming)
and [Distributions](https://docs.superfluid.org/docs/concepts/overview/distributions)
_
Real-Time Balance[](https://docs.superfluid.org/docs/concepts/overview/super-tokens#real-time-balance "Direct link to Real-Time Balance")
-------------------------------------------------------------------------------------------------------------------------------------------
Super Tokens track an account's balance dynamically, factoring in both regular transfers and impacts from Money Streaming and Distributions.
* **Static Balance**: The standard ERC20 balance affected by lump-sum transfers.
* **Real-Time Balances**: The ongoing impact of each Super Agreement on an account's balance, which can be positive or negative.
The actual current balance is a sum of these components.
> **Current Balance Formula**: Current Balance = Real-Time Balances + Static Balance
### Example Calculation[](https://docs.superfluid.org/docs/concepts/overview/super-tokens#example-calculation "Direct link to Example Calculation")
* Account A's Static Balance: 1,000 USDCx
* Account A's Stream Out: -100 USDCx
* Account A's Instant Distribution Receipts: +200 USDCx
> **Current Balance**: 1000 - 100 + 200 = **1100 USDCx**
About Super Tokens `balanceOf()`
If you are familiar with the ERC20 standard, you are certainly familiar with `balanceOf()`. A Super Token `balanceOf()` function reflects this dynamic balance, unlike a regular ERC20's static approach.
* [Wrapper Super Tokens](https://docs.superfluid.org/docs/concepts/overview/super-tokens#wrapper-super-tokens)
* [Pure Super Tokens](https://docs.superfluid.org/docs/concepts/overview/super-tokens#pure-super-tokens)
* [Real-Time Balance](https://docs.superfluid.org/docs/concepts/overview/super-tokens#real-time-balance)
* [Example Calculation](https://docs.superfluid.org/docs/concepts/overview/super-tokens#example-calculation)
---
# Deploy a Super Token | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/category/deploy-a-super-token#__docusaurus_skipToContent_fallback)
[📄️ Deploy a Wrapper Super Token\
--------------------------------\
\
This guide offers detailed instructions for deploying Wrapped Super Tokens using the Super Token Factory contract.](https://docs.superfluid.org/docs/protocol/super-tokens/guides/deploy-super-token/deploy-wrapped-super-token)
[📄️ Deploy a Pure Super Token\
-----------------------------\
\
This guide offers detailed instructions for deploying Pure Super Tokens.](https://docs.superfluid.org/docs/protocol/super-tokens/guides/deploy-super-token/deploy-pure-super-token)
[📄️ Deploying a Custom Super Token\
----------------------------------\
\
This guide will walk you through the process of deploying a Custom Super Token for the Superfluid protocol.](https://docs.superfluid.org/docs/protocol/super-tokens/guides/deploy-super-token/deploy-custom-super-token)
---
# CFAv1Forwarder | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#__docusaurus_skipToContent_fallback)
On this page
The **CFAv1Forwarder** contract is a Superfluid forwarder that implements the Constant Flow Agreement (CFA) related functions. It is a contract specifically made immutable in order to facilitate the interaction with [Money Streaming](https://docs.superfluid.org/docs/protocol/money-streaming/overview)
through the Constant Flow Agreement (CFA).
This contract is optimized for interaction that would happen from your client application. For more information on the best practices regarding this interaction, please refer to the [Create, Update and Delete Flows](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow)
or [Manage Access Control and User Data](https://docs.superfluid.org/docs/sdk/money-streaming/acl-user-data)
.
Contract Address[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#contract-address "Direct link to Contract Address")
--------------------------------------------------------------------------------------------------------------------------------------------
The `CFAv1Forwarder` contract address is the same on all networks:
0xcfA132E353cB4E398080B9700609bb008eceB125
ABI[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#abi "Direct link to ABI")
-----------------------------------------------------------------------------------------------------
In order to interact with the `CFAv1Forwarder` contract, you can use the following ABI:
Click here to show `CFAv1Forwarder` ABI
[ { "inputs": [ { "internalType": "contract ISuperfluid", "name": "host", "type": "address" } ], "stateMutability": "nonpayable", "type": "constructor" }, { "inputs": [], "name": "CFA_FWD_INVALID_FLOW_RATE", "type": "error" }, { "inputs": [ { "internalType": "contract ISuperToken", "name": "token", "type": "address" }, { "internalType": "address", "name": "sender", "type": "address" }, { "internalType": "address", "name": "receiver", "type": "address" }, { "internalType": "int96", "name": "flowrate", "type": "int96" }, { "internalType": "bytes", "name": "userData", "type": "bytes" } ], "name": "createFlow", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "contract ISuperToken", "name": "token", "type": "address" }, { "internalType": "address", "name": "sender", "type": "address" }, { "internalType": "address", "name": "receiver", "type": "address" }, { "internalType": "bytes", "name": "userData", "type": "bytes" } ], "name": "deleteFlow", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "contract ISuperToken", "name": "token", "type": "address" }, { "internalType": "address", "name": "account", "type": "address" } ], "name": "getAccountFlowInfo", "outputs": [ { "internalType": "uint256", "name": "lastUpdated", "type": "uint256" }, { "internalType": "int96", "name": "flowrate", "type": "int96" }, { "internalType": "uint256", "name": "deposit", "type": "uint256" }, { "internalType": "uint256", "name": "owedDeposit", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "contract ISuperToken", "name": "token", "type": "address" }, { "internalType": "address", "name": "account", "type": "address" } ], "name": "getAccountFlowrate", "outputs": [ { "internalType": "int96", "name": "flowrate", "type": "int96" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "contract ISuperToken", "name": "token", "type": "address" }, { "internalType": "int96", "name": "flowrate", "type": "int96" } ], "name": "getBufferAmountByFlowrate", "outputs": [ { "internalType": "uint256", "name": "bufferAmount", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "contract ISuperToken", "name": "token", "type": "address" }, { "internalType": "address", "name": "sender", "type": "address" }, { "internalType": "address", "name": "receiver", "type": "address" } ], "name": "getFlowInfo", "outputs": [ { "internalType": "uint256", "name": "lastUpdated", "type": "uint256" }, { "internalType": "int96", "name": "flowrate", "type": "int96" }, { "internalType": "uint256", "name": "deposit", "type": "uint256" }, { "internalType": "uint256", "name": "owedDeposit", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "contract ISuperToken", "name": "token", "type": "address" }, { "internalType": "address", "name": "sender", "type": "address" }, { "internalType": "address", "name": "flowOperator", "type": "address" } ], "name": "getFlowOperatorPermissions", "outputs": [ { "internalType": "uint8", "name": "permissions", "type": "uint8" }, { "internalType": "int96", "name": "flowrateAllowance", "type": "int96" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "contract ISuperToken", "name": "token", "type": "address" }, { "internalType": "address", "name": "sender", "type": "address" }, { "internalType": "address", "name": "receiver", "type": "address" } ], "name": "getFlowrate", "outputs": [ { "internalType": "int96", "name": "flowrate", "type": "int96" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "contract ISuperToken", "name": "token", "type": "address" }, { "internalType": "address", "name": "flowOperator", "type": "address" } ], "name": "grantPermissions", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "contract ISuperToken", "name": "token", "type": "address" }, { "internalType": "address", "name": "flowOperator", "type": "address" } ], "name": "revokePermissions", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "contract ISuperToken", "name": "token", "type": "address" }, { "internalType": "address", "name": "receiver", "type": "address" }, { "internalType": "int96", "name": "flowrate", "type": "int96" } ], "name": "setFlowrate", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "contract ISuperToken", "name": "token", "type": "address" }, { "internalType": "address", "name": "sender", "type": "address" }, { "internalType": "address", "name": "receiver", "type": "address" }, { "internalType": "int96", "name": "flowrate", "type": "int96" } ], "name": "setFlowrateFrom", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "contract ISuperToken", "name": "token", "type": "address" }, { "internalType": "address", "name": "sender", "type": "address" }, { "internalType": "address", "name": "receiver", "type": "address" }, { "internalType": "int96", "name": "flowrate", "type": "int96" }, { "internalType": "bytes", "name": "userData", "type": "bytes" } ], "name": "updateFlow", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "contract ISuperToken", "name": "token", "type": "address" }, { "internalType": "address", "name": "flowOperator", "type": "address" }, { "internalType": "uint8", "name": "permissions", "type": "uint8" }, { "internalType": "int96", "name": "flowrateAllowance", "type": "int96" } ], "name": "updateFlowOperatorPermissions", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "nonpayable", "type": "function" }]
CFA\_FWD\_INVALID\_FLOW\_RATE[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#cfa_fwd_invalid_flow_rate "Direct link to CFA_FWD_INVALID_FLOW_RATE")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
error CFA_FWD_INVALID_FLOW_RATE()
\_cfa[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#_cfa "Direct link to _cfa")
---------------------------------------------------------------------------------------------------------
contract IConstantFlowAgreementV1 _cfa
Fn constructor[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-constructor "Direct link to Fn constructor")
--------------------------------------------------------------------------------------------------------------------------------------
function constructor( contract ISuperfluid host) public
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#parameters "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `host` | contract ISuperfluid | |
Fn setFlowrate[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-setflowrate "Direct link to Fn setFlowrate")
--------------------------------------------------------------------------------------------------------------------------------------
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#parameters-1 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | Super token address |
| `receiver` | address | The receiver of the flow |
| `flowrate` | int96 | The wanted flowrate in wad/second. Only positive values are valid here. |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#return-values "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | bool | bool |
Sets the given flowrate between msg.sender and a given receiver. If there's no pre-existing flow and `flowrate` non-zero, a new flow is created. If there's an existing flow and `flowrate` non-zero, the flowrate of that flow is updated. If there's an existing flow and `flowrate` zero, the flow is deleted. If the existing and given flowrate are equal, no action is taken. On creation of a flow, a "buffer" amount is automatically detracted from the sender account's available balance. If the sender account is solvent when the flow is deleted, this buffer is redeemed to it.
Fn setFlowrateFrom[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-setflowratefrom "Direct link to Fn setFlowrateFrom")
--------------------------------------------------------------------------------------------------------------------------------------------------
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#parameters-2 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | Super token address |
| `sender` | address | The sender of the flow |
| `receiver` | address | The receiver of the flow |
| `flowrate` | int96 | The wanted flowrate in wad/second. Only positive values are valid here. |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#return-values-1 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | bool | bool |
Like `setFlowrate`, but can be invoked by an account with flowOperator permissions on behalf of the sender account.
Fn getFlowrate[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-getflowrate "Direct link to Fn getFlowrate")
--------------------------------------------------------------------------------------------------------------------------------------
_Currently, only 0 or 1 flows can exist between 2 accounts. This may change in the future._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#parameters-3 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | Super token address |
| `sender` | address | The sender of the flow |
| `receiver` | address | The receiver of the flow |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#return-values-2 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `flowrate` | int96 | The flowrate from the sender to the receiver account. Returns 0 if no flow exists. |
Get the flowrate of the flow between 2 accounts if exists.
Fn getFlowInfo[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-getflowinfo "Direct link to Fn getFlowInfo")
--------------------------------------------------------------------------------------------------------------------------------------
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#parameters-4 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | Super token address |
| `sender` | address | The sender of the flow |
| `receiver` | address | The receiver of the flow |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#return-values-3 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `lastUpdated` | uint256 | Timestamp of last update (flowrate change) or zero if no flow exists |
| `flowrate` | int96 | Current flowrate of the flow or zero if no flow exists |
| `deposit` | uint256 | Deposit amount locked as security buffer during the lifetime of the flow |
| `owedDeposit` | uint256 | Extra deposit amount borrowed to a SuperApp receiver by the flow sender |
Get all available information about a flow (if exists). If only the flowrate is needed, consider using `getFlowrate` instead.
Fn getBufferAmountByFlowrate[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-getbufferamountbyflowrate "Direct link to Fn getBufferAmountByFlowrate")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function getBufferAmountByFlowrate( contract ISuperToken token, int96 flowrate) external returns (uint256 bufferAmount)
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#parameters-5 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | Super token address |
| `flowrate` | int96 | The flowrate for which the buffer amount is calculated |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#return-values-4 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `bufferAmount` | uint256 | The buffer amount required for the given configuration. |
Get the buffer amount required for the given token and flowrate. This amount can vary based on the combination of token, flowrate and chain being queried. The result for a given set of parameters can change over time, because it depends on governance configurable protocol parameters. Changes of the required buffer amount affect only flows created or updated after the change.
Fn getAccountFlowrate[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-getaccountflowrate "Direct link to Fn getAccountFlowrate")
-----------------------------------------------------------------------------------------------------------------------------------------------------------
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#parameters-6 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | Super token address |
| `account` | address | Account to query |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#return-values-5 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `flowrate` | int96 | The net flowrate (aggregate incoming minus aggregate outgoing flowrate), can be negative. |
Get the net flowrate of an account.
Fn getAccountFlowInfo[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-getaccountflowinfo "Direct link to Fn getAccountFlowInfo")
-----------------------------------------------------------------------------------------------------------------------------------------------------------
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#parameters-7 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | Super token address |
| `account` | address | Account to query |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#return-values-6 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `lastUpdated` | uint256 | Timestamp of last update of a flow to or from the account (flowrate change) |
| `flowrate` | int96 | Current net aggregate flowrate |
| `deposit` | uint256 | Aggregate deposit amount currently locked as security buffer for outgoing flows |
| `owedDeposit` | uint256 | Aggregate extra deposit amount currently borrowed to SuperApps receiving from this account |
Get aggregated flow information (if any exist) of an account. If only the net flowrate is needed, consider using `getAccountFlowrate` instead.
Fn createFlow[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-createflow "Direct link to Fn createFlow")
-----------------------------------------------------------------------------------------------------------------------------------
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#parameters-8 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | Super token address |
| `sender` | address | Sender address of the flow |
| `receiver` | address | Receiver address of the flow |
| `flowrate` | int96 | The flowrate in wad/second to be set initially |
| `userData` | bytes | (optional) User data to be set. Should be set to zero if not needed. |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#return-values-7 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | bool | bool |
Low-level wrapper of createFlow/createFlowByOperator. If the address of msg.sender is not the same as the address of the `sender` argument, createFlowByOperator is used internally. In this case msg.sender needs to have permission to create flows on behalf of the given sender account with sufficient flowRateAllowance. Currently, only 1 flow can exist between 2 accounts, thus `createFlow` will fail if one already exists.
Fn updateFlow[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-updateflow "Direct link to Fn updateFlow")
-----------------------------------------------------------------------------------------------------------------------------------
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#parameters-9 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | Super token address |
| `sender` | address | Sender address of the flow |
| `receiver` | address | Receiver address of the flow |
| `flowrate` | int96 | The flowrate in wad/second the flow should be updated to |
| `userData` | bytes | (optional) User data to be set. Should be set to zero if not needed. |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#return-values-8 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | bool | bool |
Low-level wrapper if updateFlow/updateFlowByOperator. If the address of msg.sender doesn't match the address of the `sender` argument, updateFlowByOperator is invoked. In this case msg.sender needs to have permission to update flows on behalf of the given sender account with sufficient flowRateAllowance.
Fn deleteFlow[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-deleteflow "Direct link to Fn deleteFlow")
-----------------------------------------------------------------------------------------------------------------------------------
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#parameters-10 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | Super token address |
| `sender` | address | Sender address of the flow |
| `receiver` | address | Receiver address of the flow |
| `userData` | bytes | (optional) User data to be set. Should be set to zero if not needed. |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#return-values-9 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | bool | bool |
Low-level wrapper of deleteFlow/deleteFlowByOperator. If msg.sender isn't the same as sender address, msg.sender needs to have permission to delete flows on behalf of the given sender account.
Fn grantPermissions[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-grantpermissions "Direct link to Fn grantPermissions")
-----------------------------------------------------------------------------------------------------------------------------------------------------
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#parameters-11 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | Super token address |
| `flowOperator` | address | Account to which permissions are granted |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#return-values-10 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | bool | bool |
Grants a flowOperator permission to create/update/delete flows on behalf of msg.sender. In order to restrict what a flowOperator can or can't do, the flowOperator account should be a contract implementing the desired restrictions.
Fn revokePermissions[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-revokepermissions "Direct link to Fn revokePermissions")
--------------------------------------------------------------------------------------------------------------------------------------------------------
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#parameters-12 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | Super token address |
| `flowOperator` | address | Account from which permissions are revoked |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#return-values-11 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | bool | bool |
Revokes all permissions previously granted to a flowOperator by msg.sender. Revocation doesn't undo or reset flows previously created/updated by the flowOperator. In order to be sure about the state of flows at the time of revocation, you need to check that state either in the same transaction or after this transaction.
Fn updateFlowOperatorPermissions[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-updateflowoperatorpermissions "Direct link to Fn updateFlowOperatorPermissions")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#parameters-13 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | Super token address |
| `flowOperator` | address | Account for which permissions are set on behalf of msg.sender |
| `permissions` | uint8 | Bitmask for create/update/delete permission flags. See library `FlowOperatorDefinitions` |
| `flowrateAllowance` | int96 | Max. flowrate in wad/second the operator can set for individual flows. |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#return-values-12 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | bool | bool |
Low-level wrapper of `IConstantFlowAgreementV1.updateFlowOperatorPermissions` flowrateAllowance does NOT restrict the net flowrate a flowOperator is able to set. In order to restrict that, flowOperator needs to be a contract implementing the wanted limitations.
Fn getFlowOperatorPermissions[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-getflowoperatorpermissions "Direct link to Fn getFlowOperatorPermissions")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#parameters-14 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | Super token address |
| `sender` | address | The account which (possibly) granted permissions |
| `flowOperator` | address | Account to which (possibly) permissions were granted |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#return-values-13 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `permissions` | uint8 | A bitmask of the permissions currently granted (or not) by `sender` to `flowOperator` |
| `flowrateAllowance` | int96 | Max. flowrate in wad/second the flowOperator can set for individual flows. |
Get the currently set permissions granted to the given flowOperator by the given sender account.
Fn \_setFlowrateFrom[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-_setflowratefrom "Direct link to Fn _setFlowrateFrom")
------------------------------------------------------------------------------------------------------------------------------------------------------
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#parameters-15 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | |
| `sender` | address | |
| `receiver` | address | |
| `flowrate` | int96 | |
Fn \_createFlow[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-_createflow "Direct link to Fn _createFlow")
---------------------------------------------------------------------------------------------------------------------------------------
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#parameters-16 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | |
| `sender` | address | |
| `receiver` | address | |
| `flowrate` | int96 | |
| `userData` | bytes | |
Fn \_updateFlow[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-_updateflow "Direct link to Fn _updateFlow")
---------------------------------------------------------------------------------------------------------------------------------------
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#parameters-17 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | |
| `sender` | address | |
| `receiver` | address | |
| `flowrate` | int96 | |
| `userData` | bytes | |
Fn \_deleteFlow[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-_deleteflow "Direct link to Fn _deleteFlow")
---------------------------------------------------------------------------------------------------------------------------------------
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#parameters-18 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | |
| `sender` | address | |
| `receiver` | address | |
| `userData` | bytes | |
Fn \_updateFlowOperatorPermissions[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-_updateflowoperatorpermissions "Direct link to Fn _updateFlowOperatorPermissions")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#parameters-19 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | |
| `flowOperator` | address | |
| `permissions` | uint8 | |
| `flowrateAllowance` | int96 | |
* [Contract Address](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#contract-address)
* [ABI](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#abi)
* [CFA\_FWD\_INVALID\_FLOW\_RATE](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#cfa_fwd_invalid_flow_rate)
* [\_cfa](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#_cfa)
* [Fn constructor](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-constructor)
* [Fn setFlowrate](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-setflowrate)
* [Fn setFlowrateFrom](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-setflowratefrom)
* [Fn getFlowrate](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-getflowrate)
* [Fn getFlowInfo](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-getflowinfo)
* [Fn getBufferAmountByFlowrate](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-getbufferamountbyflowrate)
* [Fn getAccountFlowrate](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-getaccountflowrate)
* [Fn getAccountFlowInfo](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-getaccountflowinfo)
* [Fn createFlow](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-createflow)
* [Fn updateFlow](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-updateflow)
* [Fn deleteFlow](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-deleteflow)
* [Fn grantPermissions](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-grantpermissions)
* [Fn revokePermissions](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-revokepermissions)
* [Fn updateFlowOperatorPermissions](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-updateflowoperatorpermissions)
* [Fn getFlowOperatorPermissions](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-getflowoperatorpermissions)
* [Fn \_setFlowrateFrom](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-_setflowratefrom)
* [Fn \_createFlow](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-_createflow)
* [Fn \_updateFlow](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-_updateflow)
* [Fn \_deleteFlow](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-_deleteflow)
* [Fn \_updateFlowOperatorPermissions](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder#fn-_updateflowoperatorpermissions)
---
# Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#__docusaurus_skipToContent_fallback)
On this page
In this page we will explain Distribution Pools and show you the most relevant ways to interact with them through the Super Token interface. To do this, we will go through some key concepts, and show you how to leverage Superfluid's [`SuperTokenV1Library.sol`](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library)
for your Distribution Pools smart contracts.
About `SuperTokenV1Library.sol`
The [`SuperTokenV1Library.sol`](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library)
is a comprehensive library which makes it more convenient to use invoke Superfluid specific functionality on Super Tokens.
About the General Distributions Agreement - GDA
At times, we use "Distribution Pools" or the "General Distributions Agreement (GDA)" interchangeably due to "GDA" being the name of the implementation in our [codebase](https://github.com/superfluid-finance/protocol-monorepo)
.
What is a Pool?[](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#what-is-a-pool "Direct link to What is a Pool?")
-----------------------------------------------------------------------------------------------------------------------------------------
A pool is a smart contract that facilitates the distribution of tokens to multiple members, managed by a pool admin. Members hold units within the pool that determine their proportion of the distribution.
_A visualization of units in a pool_
note
The Superfluid pool implements basic ERC20 functionality, allowing it to interact seamlessly with [ERC20](https://docs.openzeppelin.com/contracts/4.x/erc20)
standards. This allows you to interact with the pool units as if they were ERC20 tokens, including transferring them to other addresses, if it is allowed by the pool configuration. Check the [next section](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#important-functions)
for more information on pool configurations.
About Member Units[](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#about-member-units "Direct link to About Member Units")
---------------------------------------------------------------------------------------------------------------------------------------------------
### How is a member's share of the pool determined?[](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#how-is-a-members-share-of-the-pool-determined "Direct link to How is a member's share of the pool determined?")
A pool member's units determine their share of the pool's distributions. In the background, the calculation of each member's share is calculated following these two steps:
1. **Calculating the flow rate per unit:** We calculate the flow rate or amount of tokens to be distributed _per unit_ like so:

2. **Calculating the flow rate for each member:** We multiply the flow rate per unit by the number of units each member has to get the flow rate for each member, as follows:

One of the limitations of Solidity is its incapacity to handle floating point numbers. This makes it so that the flow rate per unit is calculated as an integer. If the result of the division is not an integer, the result is rounded down.
### Examples[](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#examples "Direct link to Examples")
The examples below show how the flow rate per unit is calculated in different scenarios where Distributions reach their limitations
1. **Example 1:** Let's take a pool that has 100 wei/second as total flow rate and 3 members, each member has 1 unit.
* The flow rate per unit is 100 / 3 = 33.33
* However, since Solidity can't handle floating point numbers, the flow rate per unit is 33
* The pool distributes 33 tokens to each unit
* 1 token is left undistributed
2. **Example 2:** Let's take a pool that has 100 wei/second as total flow rate and 200 members, each member has 1 units.
* The flow rate per unit is 100 / 200 = 0.5
* However, since Solidity can't handle floating point numbers, the flow rate per unit is 0
* The pool distributes 0 tokens to each unit
* 200 tokens are left undistributed
These examples are extreme and almost never happen in practice. However, it is important to be aware of these limitations when designing your pools.
How to design your pools?
The best way to design your pools is to make sure that the total flow rate or the tokens distributed are always orders of magnitude higher than the number of total units in the pool. This way, you can be sure that the flow rate per unit will always be significantly higher than 0 and that all members will receive a share of the distribution.
About Pool Connections and Claiming[](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#about-pool-connections-and-claiming "Direct link to About Pool Connections and Claiming")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
### What is the difference between connecting to a pool and claiming tokens?[](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#what-is-the-difference-between-connecting-to-a-pool-and-claiming-tokens "Direct link to What is the difference between connecting to a pool and claiming tokens?")
After creating a pool and assigning units to pool members, they need to connect to the pool or claim their Super Tokens in order for it to show on their balance. Simply assigning units (shares) to a member does not automatically reflect in their balance. The accumulated tokens NEED to be claimed by the member (or a different address), or the member needs to connect to the pool to start receiving their share of the Super Token Distributions.
### How can members collect their Distributions from the pool?[](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#how-can-members-collect-their-distributions-from-the-pool "Direct link to How can members collect their Distributions from the pool?")
There are two ways for members to get their streamed or transferred Super Tokens from a pool:
* **Connecting to the Pool (Recommended)**: Members should connect to the pool to start receiving their share of the Super Token Distributions in real time to their balance. This includes both Instant Distributions and Streaming Distributions. In order to connect to the pool, the member should call the `connectPool` function from the [`SuperTokenV1Library`](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library)
or [`GDAv1Forwarder`](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#fn-connectpool)
. The address calling the function should be the address of the member. Other addresses will not be able to connect a member to the pool.
* **Claiming the Tokens**: Members can claim their share of the Super Token Distributions accumulated from the pool at any time, even if they are not connected to the pool. As a matter of fact, anyone can claim the tokens on behalf of the member. To do so, the function `claimAll` from the [`SuperTokenV1Library`](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library)
or [`GDAv1Forwarder`](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#fn-claimall)
should be called with the address of the member as the argument.
Connecting to the pool includes claiming
When a member connects to the pool, they automatically claim the accumulated tokens and start receiving the distributions in real time.
Reminder
We use the `SuperTokenV1Library` to interact with the Superfluid protocol [on-chain](https://docs.superfluid.org/docs/protocol/distributions/guides/distributions-and-super-tokens/on-chain)
(from your smart contracts), while we use the forwarders (eg. `GDAv1Forwarder`) to interact with the Superfluid protocol [off-chain](https://docs.superfluid.org/docs/protocol/distributions/guides/distributions-and-super-tokens/off-chain)
(from your web3 frontend applications).
Recommendation
It is recommended to prompt users to connect to the pool as soon as possible to start receiving the distributions in real time. Depending on your use case, periodic claiming may also offer the best UX, however pool connections usually offer the best UX for real-time distributions.
### How can members disconnect from the pool?[](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#how-can-members-disconnect-from-the-pool "Direct link to How can members disconnect from the pool?")
Members can always disconnect from the pool to stop receiving distributions in real time by calling the function `disconnectPool` from the [`SuperTokenV1Library`](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library)
or [`GDAv1Forwarder`](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#fn-disconnectpool)
.
### Example[](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#example "Direct link to Example")
* **Jake** creates a pool and assigns 100 units to **Alice**, 200 units to **Bob**, and 200 units to **Charlie**.
* **Alice** connects to the pool before any Distribution is made. Thus, she's able to receive her share of the Distributions in real time when they start.
* **Jake** starts a stream of 100 tokens/second to the pool.
* **Alice** receives 20 tokens/second directly into her balance, **Bob** and **Charlie** each accumulate 40 tokens/second in the pool.
* After 100 seconds, **Alice** can already see 2000 tokens on her balance. **Bob** and **Charlie** are each eligible to get 4000 tokens, but they cannot see them on their balance just yet.
* **Bob** chooses to claim every 100 seconds, while **Charlie** chooses to connect to the pool.
* **Bob** receives periodically 4000 tokens every 100 seconds.
* By connecting to the pool, **Charlie** automatically claims the accumulated tokens, but also starts receiving tokens in real time.
Important Functions[](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#important-functions "Direct link to Important Functions")
------------------------------------------------------------------------------------------------------------------------------------------------------
Here are some of the most important functions for interacting with Superfluid pools:
Reminder
Some of this functions are available via [`SuperTokenV1Library.sol`](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library)
(contracts using that lib) only.
### createPool[](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#createpool "Direct link to createPool")
function createPool(ISuperToken token, address admin, PoolConfig memory poolConfig)
Creates a new pool with the specified admin, configuration and poolConfig.
The `PoolConfig` struct is defined as follows:
struct PoolConfig { bool transferabilityForUnitsOwner; bool distributionFromAnyAddress;}
* `transferabilityForUnitsOwner`: If true, the pool members can transfer their owned units, else, only the pool admin can manipulate the units for pool members
* `distributionFromAnyAddress`: If true, anyone can execute distributions via the pool, else, only the pool admin can execute distributions via the pool
Strong recommendation
We don't recommend setting `transferabilityForUnitsOwner` to `true` unless you have a specific use case that absolutely requires it. This can sometimes lead to unexpected behavior and security risks.
SuperTokenV1Library also provides overloaded variants setting default values for `admin` (default: `msg.sender`) and/or `poolConfig` (default: `{ transferabilityForUnitsOwner: false, distributionFromAnyAddress: true }`).
### updateMemberUnits[](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#updatememberunits "Direct link to updateMemberUnits")
This function is part of `ISuperfluidPool`, can thus be invoked on pool contracts.
function updateMemberUnits(address memberAddress, uint128 newUnits)
Updates the number of units a member has within a pool, effectively changing their share of future distributions.
Important
Keep in mind that the total amount of units in the pool needs to be significantly lower than the total flow rate or the total tokens distributed of the pool. To understand more why this is the case, please refer to the [Member Units](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#about-member-units)
section.
### claimAll[](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#claimall "Direct link to claimAll")
function claimAll(ISuperToken token, ISuperfluidPool pool, address memberAddress)
Allows a member to claim their share of the tokens from all previous distributions.
### connectPool[](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#connectpool "Direct link to connectPool")
function connectPool(ISuperToken token, ISuperfluidPool pool)
Connects a pool member to a pool.
About pool connections
The pool member needs to connect to a pool before the distribution balance is reflected in their net balance. If the distribution starts before the user is connected to the pool, the user will still receive the tokens when they connect to the pool eventually.
### disconnectPool[](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#disconnectpool "Direct link to disconnectPool")
function disconnectPool(ISuperToken token, ISuperfluidPool pool)
Disconnects a pool member from a pool.
### distribute[](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#distribute "Direct link to distribute")
function distribute(ISuperToken token, ISuperfluidPool pool, uint256 requestedAmount)
Distributes a specified amount of tokens to the pool, to be shared among members according to their units.
### distributeFlow[](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#distributeflow "Direct link to distributeFlow")
function distributeFlow(ISuperToken token, ISuperfluidPool pool, int96 requestedFlowRate)
Flow-distributes with the specified flowrate to the pool, with the flow going to members according to their units.
Example Usage[](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#example-usage "Direct link to Example Usage")
------------------------------------------------------------------------------------------------------------------------------------
Here's how you might use these functions within a smart contract to set up and manage a pool:
// Assume ISuperToken and SuperfluidPool interfaces are imported and available.contract MyPool { Using SuperTokenV1Library for ISuperToken; ISuperToken private superToken; ISuperfluidPool private pool; constructor(ISuperToken _superToken) { superToken = _superToken; // create a pool with default settings: // msg.sender is admin, non-transferrable units, anybody can distribute to it pool = superToken.createPool(); } // Use updateMemberUnits to assign units to a member. // (This will typically be a permissioned operation, it's akin to minting tokens) function updateMemberUnits(address member, uint128 units) public { pool.updateMemberUnits(member, units); } // Instant distribution of tokens to pool members proportional to their current units function distribute(uint256 amount) public { superToken.distribute(pool, amount); } // Flow distribution of tokens to pool members proportional to their current units function distributeFlow(int96 flowRate) public { superToken.distributeFlow(pool, flowRate); }}
In this example, `MyPool` creates a pool, adds a member, and makes an Instant Distribution (discreet transfer - through `distribute`) and a Streaming Distribution (continuous flow - through `distributeFlow`) using the functions from `SuperTokenV1Library.sol`.
Learn more about the `SuperTokenV1Library`
For more detailed information on the implementation and usage of `SuperTokenV1Library.sol`, refer to the [Technical Reference](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library)
.
* [What is a Pool?](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#what-is-a-pool)
* [About Member Units](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#about-member-units)
* [How is a member's share of the pool determined?](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#how-is-a-members-share-of-the-pool-determined)
* [Examples](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#examples)
* [About Pool Connections and Claiming](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#about-pool-connections-and-claiming)
* [What is the difference between connecting to a pool and claiming tokens?](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#what-is-the-difference-between-connecting-to-a-pool-and-claiming-tokens)
* [How can members collect their Distributions from the pool?](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#how-can-members-collect-their-distributions-from-the-pool)
* [How can members disconnect from the pool?](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#how-can-members-disconnect-from-the-pool)
* [Example](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#example)
* [Important Functions](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#important-functions)
* [createPool](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#createpool)
* [updateMemberUnits](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#updatememberunits)
* [claimAll](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#claimall)
* [connectPool](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#connectpool)
* [disconnectPool](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#disconnectpool)
* [distribute](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#distribute)
* [distributeFlow](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#distributeflow)
* [Example Usage](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#example-usage)
---
# Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/protocol/money-streaming/guides/create-update-delete-flow#__docusaurus_skipToContent_fallback)
On this page
This guide covers various methods for managing flows directly on the Superfluid protocol. It includes creating, updating, and deleting flows, **on chain, from another smart contracts**. This guide does NOT cover:
* How to create a flow by an operator on behalf of another account. For that, please refer to the [ACL and User Data guide](https://docs.superfluid.org/docs/protocol/money-streaming/guides/acl-user-data)
.
* How to manage flows with user data. For that, please refer to the [ACL and User Data guide](https://docs.superfluid.org/docs/protocol/money-streaming/guides/acl-user-data)
.
* How to create flows by interacting with the Money Streaming Forwarder contract from client applications. For that please refer to the [SDK section](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow)
.
Prerequisites[](https://docs.superfluid.org/docs/protocol/money-streaming/guides/create-update-delete-flow#prerequisites "Direct link to Prerequisites")
----------------------------------------------------------------------------------------------------------------------------------------------------------
Before proceeding, ensure you have:
* Familiarity with Solidity.
* Basic understanding of Superfluid and its functionalities.
* Access to a development environment for deploying or interacting with Smart Contracts.
* Importing the SuperTokenV1Library in your smart contract. For more details, refer to the [Using the SuperTokenV1Library](https://docs.superfluid.org/docs/protocol/super-tokens/guides/using-library)
.
What is a flow?[](https://docs.superfluid.org/docs/protocol/money-streaming/guides/create-update-delete-flow#what-is-a-flow "Direct link to What is a flow?")
---------------------------------------------------------------------------------------------------------------------------------------------------------------
In Superfluid terminology, a flow is a continuous stream of tokens from one account to another. It is a fundamental concept in the Superfluid protocol, enabling real-time, continuous payments between accounts.
What is the difference between a "Stream" and a "Flow"?
This is a small technicality which is not necessarily important to understand. However, in Superfluid, a "Flow" is a more general term than a "Stream". A Stream is a non-zero flow, while a zero flow is not considered a Stream.
Set the flowrate[](https://docs.superfluid.org/docs/protocol/money-streaming/guides/create-update-delete-flow#set-the-flowrate "Direct link to Set the flowrate")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
### Function `flow`[](https://docs.superfluid.org/docs/protocol/money-streaming/guides/create-update-delete-flow#function-flow "Direct link to function-flow")
This function sets the specified flowrate between sender and receiver.
/** * @dev Sets the given CFA flowrate between the caller and a given receiver. * If there's no pre-existing flow and `flowRate` non-zero, a new flow is created. * If there's an existing flow and `flowRate` non-zero, the flowRate of that flow is updated. * If there's an existing flow and `flowRate` zero, the flow is deleted. * If the existing and given flowRate are equal, no action is taken. * On creation of a flow, a "buffer" amount is automatically detracted from the sender account's available balance. * If the sender account is solvent when the flow is deleted, this buffer is redeemed to it. * @param token Super token address * @param receiver The receiver of the flow * @param flowRate The wanted flowrate in wad/second. Only positive values are valid here. * @return bool */function flow(ISuperToken token, address receiver, int96 flowRate) internal returns (bool)
when not using the lib
The CFAv1Forwarder contract has a function called `setFlowrate` which does the same.
CRUD methods[](https://docs.superfluid.org/docs/protocol/money-streaming/guides/create-update-delete-flow#crud-methods "Direct link to CRUD methods")
-------------------------------------------------------------------------------------------------------------------------------------------------------
If you want to be more explicit when changing the state of flows, you can use the following CRUD methods:
### Function: `createFlow`[](https://docs.superfluid.org/docs/protocol/money-streaming/guides/create-update-delete-flow#function-createflow "Direct link to function-createflow")
To create a flow, you need to call `createFlow` by specifying the token, sender, receiver, and flow rate.
/** * @dev Create flow * @param token The token used in flow * @param receiver The receiver of the flow * @param flowRate The desired flowRate */function createFlow(ISuperToken token, address receiver, int96 flowRate) internal returns (bool)
### Function: `updateFlow`[](https://docs.superfluid.org/docs/protocol/money-streaming/guides/create-update-delete-flow#function-updateflow "Direct link to function-updateflow")
For an existing flow, you can update the flow rate through the `updateFlow` function.
/** * @dev Update flow * @param token The token used in flow * @param receiver The receiver of the flow * @param flowRate The desired flowRate */function updateFlow(ISuperToken token, address receiver, int96 flowRate) internal returns (bool)
### Function: `deleteFlow`[](https://docs.superfluid.org/docs/protocol/money-streaming/guides/create-update-delete-flow#function-deleteflow "Direct link to function-deleteflow")
To delete an existing, you need to call `deleteFlow` and specify the token, sender, and receiver.
/** * @dev Delete flow without userData * @param token The token used in flow * @param sender The sender of the flow * @param receiver The receiver of the flow */function deleteFlow(ISuperToken token, address sender, address receiver) internal returns (bool)
Can I update or delete a non-existent flow?
No, you cannot update or delete a non-existent flow. If a flow does not exist, the function will revert.
Full list of functions
For a full list of functions related to creating, updating, and deleting flows, refer to the [SuperTokenV1Library technical reference](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library)
.
Example: Control Flows[](https://docs.superfluid.org/docs/protocol/money-streaming/guides/create-update-delete-flow#example-control-flows "Direct link to Example: Control Flows")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
For this example, we'll use the `FlowSender` contract described in the [Quickstart](https://docs.superfluid.org/docs/protocol/quickstart)
as our example to demonstrate how to write a contract with creates, updates, deletes and reads flow data.
Click here to show `FlowSender` contract
//SPDX-License-Identifier: MITpragma solidity ^0.8.23;import "@openzeppelin/contracts/token/ERC20/IERC20.sol";import { ISuperfluid, ISuperToken } from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol";import { SuperTokenV1Library } from "@superfluid-finance/ethereum-contracts/contracts/apps/SuperTokenV1Library.sol";interface IFakeDAI is IERC20 { function mint(address account, uint256 amount) external;}contract FlowSender { using SuperTokenV1Library for ISuperToken; mapping (address => bool) public accountList; ISuperToken public daix; // fDAIx address on Polygon Mumbai = 0x5D8B4C2554aeB7e86F387B4d6c00Ac33499Ed01f constructor(ISuperToken _daix) { daix = _daix; } /// @dev Mints 10,000 fDAI to this contract and wraps it all into fDAIx function gainDaiX() external { // Get address of fDAI by getting underlying token address from DAIx token IFakeDAI fdai = IFakeDAI( daix.getUnderlyingToken() ); // Mint 10,000 fDAI fdai.mint(address(this), 10000e18); // Approve fDAIx contract to spend fDAI fdai.approve(address(daix), 20000e18); // Wrap the fDAI into fDAIx daix.upgrade(10000e18); } /// @dev controls a stream with the given flowrate between this contract and the desired receiver function setStream(address receiver, int96 flowRate) external { daix.flow(receiver, flowRate); } /// @dev get flow rate between this contract and the given receiver function getFlowRate(address receiver) external view returns (int96 flowRate) { return daix.getFlowRate(address(this), receiver); }}
This contract has a few functions:
* **gainDaiX**: Mints and wraps fDAI into fDAIx (Superfluid's wrapped token).
* **setStream**: Controls a stream between the contract and a receiver
* **getFlowRate**: Reads the current flow rate of a stream.
About the `SuperTokenV1Library`
As you can see, the `FlowSender` contract uses the [`SuperTokenV1Library`](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library)
to interact with the Superfluid protocol. Instead of passing the token address to the functions, the contract uses `using SuperTokenV1Library for ISuperToken;` to access the functions directly. You can learn more about how to use the `SuperTokenV1Library` in the [Using the SuperTokenV1Library](https://docs.superfluid.org/docs/protocol/super-tokens/guides/using-library)
guide.
* [Prerequisites](https://docs.superfluid.org/docs/protocol/money-streaming/guides/create-update-delete-flow#prerequisites)
* [What is a flow?](https://docs.superfluid.org/docs/protocol/money-streaming/guides/create-update-delete-flow#what-is-a-flow)
* [Set the flowrate](https://docs.superfluid.org/docs/protocol/money-streaming/guides/create-update-delete-flow#set-the-flowrate)
* [Function `flow`](https://docs.superfluid.org/docs/protocol/money-streaming/guides/create-update-delete-flow#function-flow)
* [CRUD methods](https://docs.superfluid.org/docs/protocol/money-streaming/guides/create-update-delete-flow#crud-methods)
* [Function: `createFlow`](https://docs.superfluid.org/docs/protocol/money-streaming/guides/create-update-delete-flow#function-createflow)
* [Function: `updateFlow`](https://docs.superfluid.org/docs/protocol/money-streaming/guides/create-update-delete-flow#function-updateflow)
* [Function: `deleteFlow`](https://docs.superfluid.org/docs/protocol/money-streaming/guides/create-update-delete-flow#function-deleteflow)
* [Example: Control Flows](https://docs.superfluid.org/docs/protocol/money-streaming/guides/create-update-delete-flow#example-control-flows)
---
# Money Streaming | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/concepts/overview/money-streaming#__docusaurus_skipToContent_fallback)
On this page
Definition[](https://docs.superfluid.org/docs/concepts/overview/money-streaming#definition "Direct link to Definition")
-------------------------------------------------------------------------------------------------------------------------
Money Streaming is a process where tokens are continuously transferred from a sender to a receiver at a defined per-second rate. The result of this process is a "stream". A stream is perpetual and will continue until canceled by the sender/the receiver or the sender's Super Token balance is depleted.
**Terminology**[](https://docs.superfluid.org/docs/concepts/overview/money-streaming#terminology "Direct link to terminology")
--------------------------------------------------------------------------------------------------------------------------------
* **Flow Rate**: The rate at which the sender's balance decreases and the receiver's increases per second.
* **Netflow Rate**: The rate of change of an account's Super Token balance per second.
* **Sender**: The account initiating the stream, specifying a receiver and flow rate.
* **Receiver**: The account on the receiving end of a stream.
* [**CRUD Timestamp**](https://en.wikipedia.org/wiki/Create,_read,_update_and_delete)
: The timestamp when a stream is created, updated, or deleted.
* **Real-Time Balance**: The change in the account's Super Token balance since the last CRUD action.
* **Static Balance**: The Super Token balance at the last CRUD timestamp.
* **Current Balance**: The sum of Static Balance and Streaming Real-Time Balance.
info
**NOTE**: Flow rates are per second but can be represented in different time units for convenience. For example, "100 USDCx/mo." is approximately "0.0039 USDCx/sec."
Computation[](https://docs.superfluid.org/docs/concepts/overview/money-streaming#computation "Direct link to Computation")
----------------------------------------------------------------------------------------------------------------------------
The netflow for an account is calculated by netting its inbound and outbound streaming flow rates.
-76190dd110cbd70e7a920b7fa10caf39.png)
_Example of Net Flow calculation_
When a stream is modified, the following are updated in the Superfluid contracts:
1. New Netflow rate
2. New CRUD timestamp
3. New Static Balance: set to the Current Balance at the CRUD timestamp
4. Real-Time Balance reset to zero
The Real-Time Balance then adjusts by-the-second at the netflow rate.
_(1)-49d9bbe44c813f92bd475ace8d287ce5.png)
_Streaming Real-Time Balance_
info
**NOTE**: Creating a stream is a one-time action. The balance is dynamically calculated and does not require continuous transactions.
**Formula**[](https://docs.superfluid.org/docs/concepts/overview/money-streaming#formula "Direct link to formula")
--------------------------------------------------------------------------------------------------------------------
* **Static Balance**: Initial balance at the latest CRUD timestamp
* **Real-Time Balance**: Netflow Rate \* Seconds since the latest CRUD timestamp
* **Current Balance**: Static Balance + Real-Time Balance
Example - Monitoring Account A's Current Balance[](https://docs.superfluid.org/docs/concepts/overview/money-streaming#example---monitoring-account-as-current-balance "Direct link to Example - Monitoring Account A's Current Balance")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Let's examine how Account A's balance changes with stream interactions.
#### **1\. Starting an Outbound Stream**[](https://docs.superfluid.org/docs/concepts/overview/money-streaming#1-starting-an-outbound-stream "Direct link to 1-starting-an-outbound-stream")
_(1)_(1)-0592a4b69128c5338cbcef39d6988a51.png)
_Outbound Stream_
* Initial Balance: 1000 USDCx
* Flow Rate to Account B: 0.01 USDCx/sec
* Time Elapsed: 1000 seconds
* **Current Balance**: 990 USDCx
#### **2\. Increasing the Flow Rate**[](https://docs.superfluid.org/docs/concepts/overview/money-streaming#2-increasing-the-flow-rate "Direct link to 2-increasing-the-flow-rate")
-ed10e7a809a8ad62d89eeafe06a5851a.png)
_Flow Rate Increase_
* Static Balance: 990 USDCx
* New Flow Rate: 0.02 USDCx/sec
* **Current Balance**: 990 USDCx
#### **3\. Time Elapse Post Flow Rate Change**[](https://docs.superfluid.org/docs/concepts/overview/money-streaming#3-time-elapse-post-flow-rate-change "Direct link to 3-time-elapse-post-flow-rate-change")
_(1)-7e73f916e59ab5b81cc79bb84830094b.png)
_Time Elapse_
* Time Elapsed: 2000 seconds
* **Current Balance**: 950 USDCx
#### **4\. Receiving an Inbound Stream**[](https://docs.superfluid.org/docs/concepts/overview/money-streaming#4-receiving-an-inbound-stream "Direct link to 4-receiving-an-inbound-stream")
-27a7f29c095a1d9f498635490038ff8e.png)
_Inbound Stream_
* Inbound Flow Rate from Account C: 0.04 USDCx/sec
* **Current Balance**: 950 USDCx
#### **5\. Post Inbound Stream Time Elapse**[](https://docs.superfluid.org/docs/concepts/overview/money-streaming#5-post-inbound-stream-time-elapse "Direct link to 5-post-inbound-stream-time-elapse")
-3db75d26a091a1c0dd504a7c378b8be4.png)
_Post Inbound Stream_
* Time Elapsed: 1000 seconds
* **Current Balance**: 970 USDCx
#### **6\. Deleting the Outbound Stream**[](https://docs.superfluid.org/docs/concepts/overview/money-streaming#6-deleting-the-outbound-stream "Direct link to 6-deleting-the-outbound-stream")
-f35d509b5e265e8d0ae109fa087f847b.png)
\*Deleting Inbound Stream
* Static Balance: 970 USDCx
* **Current Balance**: 970 USDCx
Other Considerations[](https://docs.superfluid.org/docs/concepts/overview/money-streaming#other-considerations "Direct link to Other Considerations")
-------------------------------------------------------------------------------------------------------------------------------------------------------
#### Discrete Actions and Active Streams[](https://docs.superfluid.org/docs/concepts/overview/money-streaming#discrete-actions-and-active-streams "Direct link to Discrete Actions and Active Streams")
Transferring, wrapping, or unwrapping Super Tokens, being lump-sum actions, only affect the Static Balance and not the Real-Time Balance.
#### Interaction with Distributions[](https://docs.superfluid.org/docs/concepts/overview/money-streaming#interaction-with-distributions "Direct link to Interaction with Distributions")
Actions within Distributions have their own Real-Time Balance and are added separately to the overall account balance.
Solvency and Sentinels[](https://docs.superfluid.org/docs/concepts/overview/money-streaming#solvency-and-sentinels "Direct link to Solvency and Sentinels")
-------------------------------------------------------------------------------------------------------------------------------------------------------------
Accounts with negative net flow rates reaching zero balance are considered **critical**. Superfluid handles this with buffer deposits and Sentinels.
### Buffer[](https://docs.superfluid.org/docs/concepts/overview/money-streaming#buffer "Direct link to Buffer")
Buffer deposits are taken when opening a stream, serving as a reserve in case of a critical balance. If a stream is closed before hitting critical, the buffer is refunded. In cases where the account becomes critical, the buffer is used to continue outbound streams until Sentinels intervene.
### Sentinels[](https://docs.superfluid.org/docs/concepts/overview/money-streaming#sentinels "Direct link to Sentinels")
Sentinels are external actors who monitor Constant Flow Agreements (Money Streaming), close streams of critical accounts, and earn buffer deposits.
_For more details, see the [Liquidations](https://docs.superfluid.org/docs/protocol/advanced-topics/solvency/liquidations-and-toga)
and [Sentinels](https://docs.superfluid.org/docs/protocol/advanced-topics/solvency/running-a-sentinnel)
pages._
* [Definition](https://docs.superfluid.org/docs/concepts/overview/money-streaming#definition)
* [**Terminology**](https://docs.superfluid.org/docs/concepts/overview/money-streaming#terminology)
* [Computation](https://docs.superfluid.org/docs/concepts/overview/money-streaming#computation)
* [**Formula**](https://docs.superfluid.org/docs/concepts/overview/money-streaming#formula)
* [Example - Monitoring Account A's Current Balance](https://docs.superfluid.org/docs/concepts/overview/money-streaming#example---monitoring-account-as-current-balance)
* [Other Considerations](https://docs.superfluid.org/docs/concepts/overview/money-streaming#other-considerations)
* [Solvency and Sentinels](https://docs.superfluid.org/docs/concepts/overview/money-streaming#solvency-and-sentinels)
* [Buffer](https://docs.superfluid.org/docs/concepts/overview/money-streaming#buffer)
* [Sentinels](https://docs.superfluid.org/docs/concepts/overview/money-streaming#sentinels)
---
# Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/category/overview#__docusaurus_skipToContent_fallback)
[📄️ Super Tokens\
----------------\
\
Super Tokens extend the ERC20 token standard with additional functionalities like Money Streaming or Distributions, formerly known as Super Agreements. There are two types of Super Tokens: wrapper and custom.](https://docs.superfluid.org/docs/concepts/overview/super-tokens)
[📄️ Money Streaming\
-------------------\
\
Definition](https://docs.superfluid.org/docs/concepts/overview/money-streaming)
[📄️ Distributions\
-----------------\
\
The introduction of Distributions marks a significant advancement in DeFi applications, offering a scalable method for one-to-many fund transfers.](https://docs.superfluid.org/docs/concepts/overview/distributions)
---
# Use Cases | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/category/use-cases#__docusaurus_skipToContent_fallback)
[📄️ Token-Cost-Averaging\
------------------------\
\
Token-Cost-Averaging\* (TCA) is one possible application designed to leverage the power of Superfluid streams.](https://docs.superfluid.org/docs/concepts/use-cases/defi)
[📄️ Social & Community\
----------------------\
\
Superfluid Protocol introduces innovative methods for community engagement and social token incentives, fostering long-term loyalty and participation.](https://docs.superfluid.org/docs/concepts/use-cases/social-and-community)
---
# Advanced Topics | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/category/advanced-topics#__docusaurus_skipToContent_fallback)
[📄️ Super Apps\
--------------\
\
Super Apps represents a class of smart contracts that interact seamlessly with the Superfluid Protocol, enabling dynamic responses to Money streaming or Distributions (Also called Super Agreements).](https://docs.superfluid.org/docs/concepts/advanced-topics/super-apps)
[📄️ Superfluid Host\
-------------------\
\
The Superfluid Host Contract is a central element of the Superfluid Protocol, acting as a hub connecting Super Tokens, Super Agreements, and Super Apps.](https://docs.superfluid.org/docs/concepts/advanced-topics/superfluid-host)
---
# Glossary of Terms | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/concepts/glossary#__docusaurus_skipToContent_fallback)
On this page
This glossary provides a comprehensive overview of terms and concepts within the Superfluid ecosystem.
General Conceptual Terms[](https://docs.superfluid.org/docs/concepts/glossary#general-conceptual-terms "Direct link to General Conceptual Terms")
---------------------------------------------------------------------------------------------------------------------------------------------------
**Superfluid Ecosystem**: The collective of users and Super Apps utilizing real-time finance through Superfluid.
**Real-Time Finance**: The movement of money on a second-by-second basis enabled by Superfluid's smart contract framework.
Super Tokens[](https://docs.superfluid.org/docs/concepts/glossary#super-tokens "Direct link to Super Tokens")
---------------------------------------------------------------------------------------------------------------
**Super Token**: Tokens used in all Superfluid operations. Types include ERC20 Wrapper Tokens, Pure Super Tokens, and Native Asset Super Tokens. Detailed information is available in our [Super Tokens section](https://docs.superfluid.org/docs/developers/super-tokens/super-tokens/)
.
**Wrap**: The process of converting ERC20 tokens into wrapped super tokens. This involves transferring ERC20 assets into the wrapper contract and receiving an equivalent amount of super tokens.
**Unwrap**: Converting wrapped super tokens back into their underlying ERC20 assets. This involves burning super tokens and transferring the underlying asset to the user.
**Real Time Balance**: A dynamic calculation of an account's balance, considering both Superfluid agreement logic and static token balances.
Agreements[](https://docs.superfluid.org/docs/concepts/glossary#agreements "Direct link to Agreements")
---------------------------------------------------------------------------------------------------------
**Superfluid Agreement**: Additional functionalities for Super Tokens provided by the Superfluid protocol. Examples include the Constant Flow Agreement and the Instant Distribution Agreement, with potential for more in the future.
**Constant Flow Agreement (CFA)**: An agreement allowing perpetual, second-by-second movement of Super Tokens between addresses.
**Instant Distribution Agreement (IDA)**: An agreement for mass dispersion of Super Tokens to multiple addresses based on distribution shares or "units" at a fixed gas cost.
**Flow**: A continuous money stream from one address to another. A sender can maintain only one flow to the same receiver per token.
**Flow Rate**: The amount of tokens sent in a stream, denominated in wei per second.
**Net Flow Rate**: The net amount of tokens sent or received per second by an account for a specific token.
**ACL (Access Control List)**: A feature enabling varying levels of control to operators for creating, updating, or deleting streams on behalf of an account.
**Index**: A pool created using the Instant Distribution Agreement.
**Publisher**: The creator of an Index.
**Units**: Shares denoting an address’s share of an IDA index, interchangeable with "distribution shares".
**Distribution**: The action of sending tokens to addresses owning shares in an index, proportionate to the number of shares held.
Protocol[](https://docs.superfluid.org/docs/concepts/glossary#protocol "Direct link to Protocol")
---------------------------------------------------------------------------------------------------
**Callback**: A function that automatically executes when specific actions are taken. Super Apps use callbacks to respond to Superfluid-related actions.
**User Data**: Data that can be included with Superfluid function calls and utilized within Super App callbacks.
**Batch Calls**: A Super Token feature allowing multiple actions to be executed in a single transaction.
**The Superfluid Host**: The core of the protocol, processing function calls and facilitating protocol governance and Super App callbacks.
**Resolver**: A contract assisting in locating all protocol constituent contract addresses.
Sentinels & Solvency[](https://docs.superfluid.org/docs/concepts/glossary#sentinels--solvency "Direct link to Sentinels & Solvency")
--------------------------------------------------------------------------------------------------------------------------------------
**Buffer**: Tokens locked temporarily when a stream starts.
**Liquidation**: The process initiated by a sentinel when an account's balance reaches zero while streaming funds.
**Sentinel**: A node monitoring the Superfluid network and closing critical or insolvent streams. Anyone can run a sentinel node.
**PIC (Patrician in Charge)**: The recipient of rewards for closing streams during the priority period when an account becomes critical.
**TOGA (Transparent Ongoing Auction)**: An auction allowing individuals to become the PIC by staking a higher amount than the current PIC.
**Stake**: Funds locked in the TOGA contract by the PIC.
**Top Up**: Adding to a Super Token balance to prevent liquidation due to a zero balance.
* [General Conceptual Terms](https://docs.superfluid.org/docs/concepts/glossary#general-conceptual-terms)
* [Super Tokens](https://docs.superfluid.org/docs/concepts/glossary#super-tokens)
* [Agreements](https://docs.superfluid.org/docs/concepts/glossary#agreements)
* [Protocol](https://docs.superfluid.org/docs/concepts/glossary#protocol)
* [Sentinels & Solvency](https://docs.superfluid.org/docs/concepts/glossary#sentinels--solvency)
---
# Money Streaming | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/category/money-streaming#__docusaurus_skipToContent_fallback)
[📄️ Money Streaming in Superfluid\
---------------------------------\
\
Money Streaming, previously known as Constant Flow Agreement (CFA), revolutionizes the movement of tokens with a by-the-second transfer mechanism. This page provides an in-depth overview of Money Streaming and the unique aspects of Flow NFTs in the Superfluid ecosystem.](https://docs.superfluid.org/docs/protocol/money-streaming/overview)
[🗃️ Guides\
----------\
\
3 items](https://docs.superfluid.org/docs/category/guides-1)
[🗃️ Examples\
------------\
\
1 item](https://docs.superfluid.org/docs/category/examples)
---
# Money Streaming in Superfluid | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/protocol/money-streaming/overview#__docusaurus_skipToContent_fallback)
On this page
Money Streaming, previously known as Constant Flow Agreement (CFA), revolutionizes the movement of tokens with a by-the-second transfer mechanism. This page provides an in-depth overview of Money Streaming and the unique aspects of Flow NFTs in the Superfluid ecosystem.
What is Money Streaming?[](https://docs.superfluid.org/docs/protocol/money-streaming/overview#what-is-money-streaming "Direct link to What is Money Streaming?")
------------------------------------------------------------------------------------------------------------------------------------------------------------------
Money Streaming allows for continuous, per-second token transfers between accounts, offering a dynamic and flexible approach to token distribution.
### Key Characteristics[](https://docs.superfluid.org/docs/protocol/money-streaming/overview#key-characteristics "Direct link to Key Characteristics")
* **Perpetual Transfers**: Streams continue until canceled by the sender or the sender's balance depletes.
* **Flexible Management**: Streams can be created, updated, or deleted at any time by the sender.
For a more conceptual breakdown, refer to the [detailed Money Streaming overview](https://docs.superfluid.org/docs/protocol/money-streaming/overview)
.
Flows and Flow Rates[](https://docs.superfluid.org/docs/protocol/money-streaming/overview#flows-and-flow-rates "Direct link to Flows and Flow Rates")
-------------------------------------------------------------------------------------------------------------------------------------------------------
Money Streaming in Superfluid introduces the concepts of flows and flow rates, key elements for managing the continuous movement of tokens. This section defines these concepts and explains how to calculate flow rates accurately.
Flows in Superfluid represent the continuous, per-second movement of tokens between accounts. They are defined by their flow rate and can be dynamically managed by the sender.
tip
You may have a hard time seeing the difference between "Flows" and "Streams". This is a feature, not a bug. The key difference is the following: Flows can be equal to 0, while Streams need to be strictly positive.
Flows have the following Characteristics:
* **Perpetual**: Flows continue until the sender decides to cancel or the balance depletes.
* **Flexible**: Flows can be created, updated, or stopped at any time.
### Calculating Flow Rates[](https://docs.superfluid.org/docs/protocol/money-streaming/overview#calculating-flow-rates "Direct link to Calculating Flow Rates")
Flow rates dictate the speed at which tokens are transferred per second. Superfluid requires these rates to be specified in wei per second.
It's crucial to translate your desired flow rate into wei per second accurately. Incorrect calculations can lead to discrepancies between expected and actual flow rates as displayed on the Superfluid Dashboard and Explorer.
Flow Rate Conversion
Flow rates can be reframed from larger time denominations like months or years into wei per second. Understand the conversion process to accurately determine the wei/second rate for your flows.
### Calculation Examples[](https://docs.superfluid.org/docs/protocol/money-streaming/overview#calculation-examples "Direct link to Calculation Examples")
#### From Month to Wei/Second[](https://docs.superfluid.org/docs/protocol/money-streaming/overview#from-month-to-weisecond "Direct link to From Month to Wei/Second")
* **Monthly Rate**: 10 DAIx/month.
* **Calculation**: 10 DAIx / ((365/12) \* 24 \* 60 \* 60) = 3805175038052 wei/second.
#### From Year to Wei/Second[](https://docs.superfluid.org/docs/protocol/money-streaming/overview#from-year-to-weisecond "Direct link to From Year to Wei/Second")
* **Yearly Rate**: 100 DAIx/year.
* **Calculation**: 100 DAIx / (365 \* 24 \* 60 \* 60) = 3170979198376 wei/second.
Calculation Precision
Using an approximate number of days in a month (like 30 days) for calculations can lead to slightly inaccurate wei/second rates, affecting how the rate appears on Superfluid interfaces.
This section provides a clear understanding of flows and flow rates within the Superfluid Money Streaming, enabling users to accurately manage and interpret their token streams.
* [What is Money Streaming?](https://docs.superfluid.org/docs/protocol/money-streaming/overview#what-is-money-streaming)
* [Key Characteristics](https://docs.superfluid.org/docs/protocol/money-streaming/overview#key-characteristics)
* [Flows and Flow Rates](https://docs.superfluid.org/docs/protocol/money-streaming/overview#flows-and-flow-rates)
* [Calculating Flow Rates](https://docs.superfluid.org/docs/protocol/money-streaming/overview#calculating-flow-rates)
* [Calculation Examples](https://docs.superfluid.org/docs/protocol/money-streaming/overview#calculation-examples)
---
# Super Tokens | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/category/super-tokens#__docusaurus_skipToContent_fallback)
[📄️ Overview of Super Tokens\
----------------------------\
\
Super Tokens extend the ERC20 token standard by integrating additional functionalities like streams and distributions. Super Tokens exist in two primary forms: Wrapper and Pure.](https://docs.superfluid.org/docs/protocol/super-tokens/overview)
[🗃️ Guides\
----------\
\
2 items](https://docs.superfluid.org/docs/category/guides)
---
# Super Tokens | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/category/super-tokens-1#__docusaurus_skipToContent_fallback)
[📄️ Wrap and Unwrap Super Tokens\
--------------------------------\
\
This guide explains how to wrap and unwrap Wrapped Super Tokens from your client application.](https://docs.superfluid.org/docs/sdk/super-tokens/wrap-unwrap)
[📄️ Tracking Super Token Balances\
---------------------------------\
\
Super Token balances can dynamically change every second, presenting unique challenges and considerations for tracking them within the Ethereum ecosystem.](https://docs.superfluid.org/docs/sdk/super-tokens/super-token-balances)
[📄️ How to make your balance dance?\
-----------------------------------\
\
Have you ever been to the Superfluid Dashboard and seen the balance of a user dancing like in the GIF below?](https://docs.superfluid.org/docs/sdk/super-tokens/balance-dance)
---
# Distribution Pools | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/category/distribution-pools#__docusaurus_skipToContent_fallback)
[📄️ Distribution Pools Explained\
--------------------------------\
\
Introduction](https://docs.superfluid.org/docs/protocol/distributions/overview)
[🗃️ Guides\
----------\
\
3 items](https://docs.superfluid.org/docs/category/guides-2)
---
# Money Streaming | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/category/money-streaming-1#__docusaurus_skipToContent_fallback)
[📄️ Create, Update, and Delete Flows\
------------------------------------\
\
This guide covers various methods for managing flows in Superfluid from your client application side.](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow)
[📄️ Manage Access Control and User Data\
---------------------------------------\
\
This guide explains how to manage access control and user data in the Superfluid protocol from your client applications:](https://docs.superfluid.org/docs/sdk/money-streaming/acl-user-data)
[📄️ Subgraph\
------------\
\
The Graph is the indexing layer of the blockchain industry, providing a queryable platform for the vast data produced by blockchain networks.](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph)
---
# Examples | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/category/examples-2#__docusaurus_skipToContent_fallback)
[📄️ Rewards Distribution Using Macros\
-------------------------------------\
\
This guide will walk you through creating a web application that enables](https://docs.superfluid.org/docs/sdk/examples/example1)
---
# Advanced Topics | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/category/advanced-topics-1#__docusaurus_skipToContent_fallback)
[🗃️ Super Apps\
--------------\
\
4 items](https://docs.superfluid.org/docs/category/super-apps)
[🗃️ Automations\
---------------\
\
4 items](https://docs.superfluid.org/docs/category/automations)
[🗃️ Solvency\
------------\
\
3 items](https://docs.superfluid.org/docs/category/solvency)
---
# Advanced Topics | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/category/advanced-topics-2#__docusaurus_skipToContent_fallback)
[📄️ Batch transactions with Macros\
----------------------------------\
\
Superfluid's infrastructure introduces innovative approaches to batching transactions and account abstraction,](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-macro)
[📄️ Batch Calls with Host Contract\
----------------------------------\
\
Execute multiple Superfluid operations in a single transaction using the Host contract's batchCall function.](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder)
---
# Distribution Pools | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/category/distribution-pools-1#__docusaurus_skipToContent_fallback)
[📄️ Create and Manage Distribution Pools\
----------------------------------------\
\
This guide explains how to create and manage Distribution Pools in Superfluid using the GDAv1Forwarder contract.](https://docs.superfluid.org/docs/sdk/distributions/create-manage-pools)
[📄️ Connecting and Claiming from the Pools\
------------------------------------------\
\
This guide focuses on connecting and claiming from Superfluid Distribution Pools using the GDAv1Forwarder contract.](https://docs.superfluid.org/docs/sdk/distributions/connect-claim-pool)
[📄️ Subgraph\
------------\
\
The Graph is the indexing layer of our industry, providing a queryable platform for the vast data produced by blockchain networks. The Graph can be used for querying data in the Superfluid ecosystem and other on-chain data. Experiment with queries using the GraphQL Playground.](https://docs.superfluid.org/docs/sdk/distributions/subgraph)
---
# Examples | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/category/examples-1#__docusaurus_skipToContent_fallback)
[📄️ Advertisement Auction DApp\
------------------------------\
\
This guide explores the development of a decentralized application (DApp) for an advertisement auction system, leveraging the capabilities of Superfluid's Distribution Pools (also called the General Distributions Agreement - GDA).](https://docs.superfluid.org/docs/protocol/examples/example1)
[📄️ Staking Platform\
--------------------\
\
This guide explores the development of a staking platform, leveraging the capabilities of Superfluid's Distribution Pools (also called the General Distributions Agreement - GDA).](https://docs.superfluid.org/docs/protocol/examples/example2)
---
# Contribute | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/category/contribute#__docusaurus_skipToContent_fallback)
[📄️ Bounty Program\
------------------\
\
The Superfluid Bounty Program allows developers to tackle a variety of technical issues laid out by the Superfluid Team and earn payouts for completion. Ready to get bounty hunting? Let's get started!](https://docs.superfluid.org/docs/protocol/contribute/bounty-program)
[📄️ Security & Bug Bounties\
---------------------------\
\
Immunefi Bug Bounty Program](https://docs.superfluid.org/docs/protocol/contribute/bug-bounties)
[📄️ Token Explorer Submission\
-----------------------------\
\
You want your token to show up on the Superfluid Explorer? Look no further.](https://docs.superfluid.org/docs/protocol/contribute/submit-token-dashboard)
---
# Contract Addresses | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/protocol/contract-addresses#__docusaurus_skipToContent_fallback)
On this page
This section provides an overview of the Superfluid Protocol's main smart contracts and their respective addresses on the supported chains. For a detailed list of all contract addresses, refer to the [Superfluid Explorer](https://explorer.superfluid.finance/)
.
Table of Contract Addresses[](https://docs.superfluid.org/docs/protocol/contract-addresses#table-of-contract-addresses "Direct link to Table of Contract Addresses")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
The Superfluid Protocol is composed of several smart contracts that interact with each other to facilitate real-time finance on the blockchain. Below is a table of the main contracts and their respective addresses on the all chains.
Loading...
For more information on the Superfluid Protocol's contract addresses, please refer to the [Superfluid Explorer](https://explorer.superfluid.finance/)
.
Protocol Architecture[](https://docs.superfluid.org/docs/protocol/contract-addresses#protocol-architecture "Direct link to Protocol Architecture")
----------------------------------------------------------------------------------------------------------------------------------------------------
To learn more about the Superfluid Protocol's architecture, refer to the [Architecture Section](https://docs.superfluid.org/docs/technical-reference/architecture)
.
* [Table of Contract Addresses](https://docs.superfluid.org/docs/protocol/contract-addresses#table-of-contract-addresses)
* [Protocol Architecture](https://docs.superfluid.org/docs/protocol/contract-addresses#protocol-architecture)
---
# Overview of Super Tokens | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/protocol/super-tokens/overview#__docusaurus_skipToContent_fallback)
On this page
Super Tokens extend the ERC20 token standard by integrating additional functionalities like streams and distributions. Super Tokens exist in two primary forms: Wrapper and Pure.
Real-Time Balance[](https://docs.superfluid.org/docs/protocol/super-tokens/overview#real-time-balance "Direct link to Real-Time Balance")
-------------------------------------------------------------------------------------------------------------------------------------------
Super Tokens revolutionize balance calculations by combining traditional static balances with dynamic, real-time adjustments based on streams and distributions, leading to a more fluid representation of an account's value.
Characteristics of Super Tokens:
* **Static Balance**: Reflects the conventional ERC20 balance, representing the basic, unchanging part of an account's value.
* **Real-Time Balances**: Incorporates fluctuations from streams and distributions, adjusting the balance with each block to reflect ongoing financial activities. When you call the method `balanceOf()` on a Super Token, you get a real-time balance.
* **Complex Calculation**: Unlike conventional tokens, `balanceOf()` method in Super Tokens doesn't just retrieve a stored value; it performs complex calculations based on numerous parameters to give the real time balance.
* **Ongoing Relationships**: These calculations consider the account's continuous relationships with others, making the balance more representative of the current financial state.
* **Time-Sensitive**: In cases involving streams, the balance is further influenced by time, specifically through the timestamp of the latest block, making it sensitive to the passage of time.
* **Dynamic Adjustment**: As a result, the balance is a "real-time balance," capable of changing with every new block, independent of direct transactions affecting the account.
Types of Super Tokens[](https://docs.superfluid.org/docs/protocol/super-tokens/overview#types-of-super-tokens "Direct link to Types of Super Tokens")
-------------------------------------------------------------------------------------------------------------------------------------------------------
* Wrapper Super Tokens
* Pure Super Tokens
* Native Super Tokens
### 1\. Wrapper Super Tokens[](https://docs.superfluid.org/docs/protocol/super-tokens/overview#1-wrapper-super-tokens "Direct link to 1. Wrapper Super Tokens")
Wrapper Super Tokens are wrapped from existing ERC20 tokens to allow interaction with the Superfluid Protocol. They are the most common currently and can be permissionlessly created for any ERC20 token.
#### Wrapping & Unwrapping[](https://docs.superfluid.org/docs/protocol/super-tokens/overview#wrapping--unwrapping "Direct link to Wrapping & Unwrapping")
* **Wrapping**: Deposit ERC20 tokens into the Wrapper Super Token contract to mint an equivalent amount of Super Tokens.
* **Unwrapping**: Burn Super Tokens to get back the underlying ERC20 tokens.
#### When to use Custom Wrappers?[](https://docs.superfluid.org/docs/protocol/super-tokens/overview#when-to-use-custom-wrappers "Direct link to When to use Custom Wrappers?")
* **Unconventional ERC-20**: Custom Wrapper Super Tokens are typically used when underlying ERC20 tokens have complex functionalities that standard wrappers can't handle.
* **Additional Features**: They can also be used to add additional features to the Super Token which don't exist in the Super Token contract.
For detailed deployment steps and further information, visit the [Deploy a Super Token Page](https://docs.superfluid.org/docs/protocol/super-tokens/guides/deploy-super-token/deploy-wrapped-super-token)
.
### 2\. Pure Super Tokens[](https://docs.superfluid.org/docs/protocol/super-tokens/overview#2-pure-super-tokens "Direct link to 2. Pure Super Tokens")
Pure Super Tokens are independent of any underlying asset, inheriting all Superfluid functionalities directly.
#### Customization[](https://docs.superfluid.org/docs/protocol/super-tokens/overview#customization "Direct link to Customization")
Pure Super Tokens can be customized with additional features like pre-minting, access control, and wallet whitelisting. They can be categorized as Governed or Independent, with Governed Pure Super Tokens recommended for alignment with Superfluid Protocol Governance.
For a step-by-step guide on deploying Pure Super Tokens, refer to the [Pure Super Token Deployment](https://docs.superfluid.org/docs/protocol/super-tokens/guides/deploy-super-token/deploy-pure-super-token)
section.
### 3\. Native Super Tokens[](https://docs.superfluid.org/docs/protocol/super-tokens/overview#3-native-super-tokens "Direct link to 3. Native Super Tokens")
Native Super Tokens are similar to wrappers but are designed for native assets like ETH, MATIC, or AVAX. Depositing these assets into the Native Super Token contract yields a wrapped version of the asset.
Canonical deployments of Native Super Tokens are available for each chain that Superfluid operates on. For detailed deployment steps and further information, visit the [Deploy a Super Token Page](https://docs.superfluid.org/docs/protocol/super-tokens/guides/deploy-super-token/deploy-wrapped-super-token)
.
* [Real-Time Balance](https://docs.superfluid.org/docs/protocol/super-tokens/overview#real-time-balance)
* [Types of Super Tokens](https://docs.superfluid.org/docs/protocol/super-tokens/overview#types-of-super-tokens)
* [1\. Wrapper Super Tokens](https://docs.superfluid.org/docs/protocol/super-tokens/overview#1-wrapper-super-tokens)
* [2\. Pure Super Tokens](https://docs.superfluid.org/docs/protocol/super-tokens/overview#2-pure-super-tokens)
* [3\. Native Super Tokens](https://docs.superfluid.org/docs/protocol/super-tokens/overview#3-native-super-tokens)
---
# GDAv1Forwarder | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#__docusaurus_skipToContent_fallback)
On this page
The **GDAv1Forwarder** contract is a Superfluid forwarder that implements the General Distribution Agreement (GDA) related functions. It is a contract specifically made immutable in order to facilitate the interaction with [Distributions](https://docs.superfluid.org/docs/protocol/distributions/overview)
through the General Distribution Agreement (GDA).
This contract is optimized for interaction that would happen from outside the blockchain (off-chain). For more information on the best practices regarding this interaction, please refer to the [SDK Section](https://docs.superfluid.org/docs/sdk/quickstart)
section of this documentation.
Contract Address[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#contract-address "Direct link to Contract Address")
--------------------------------------------------------------------------------------------------------------------------------------------
The `GDAv1Forwarder` contract address is the same on all Superfluid chains:
0x6DA13Bde224A05a288748d857b9e7DDEffd1dE08
ABI[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#abi "Direct link to ABI")
-----------------------------------------------------------------------------------------------------
In order to interact with the `GDAv1Forwarder` contract, you can use the following ABI:
Click here to show `GDAv1Forwarder` ABI
[ { "inputs": [ { "internalType": "contract ISuperfluid", "name": "host", "type": "address" } ], "stateMutability": "nonpayable", "type": "constructor" }, { "inputs": [ { "internalType": "contract ISuperfluidPool", "name": "pool", "type": "address" }, { "internalType": "address", "name": "memberAddress", "type": "address" }, { "internalType": "bytes", "name": "userData", "type": "bytes" } ], "name": "claimAll", "outputs": [{ "internalType": "bool", "name": "success", "type": "bool" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "contract ISuperfluidPool", "name": "pool", "type": "address" }, { "internalType": "bytes", "name": "userData", "type": "bytes" } ], "name": "connectPool", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "contract ISuperfluidToken", "name": "token", "type": "address" }, { "internalType": "address", "name": "admin", "type": "address" }, { "components": [ { "internalType": "bool", "name": "transferabilityForUnitsOwner", "type": "bool" }, { "internalType": "bool", "name": "distributionFromAnyAddress", "type": "bool" } ], "internalType": "struct PoolConfig", "name": "config", "type": "tuple" } ], "name": "createPool", "outputs": [ { "internalType": "bool", "name": "success", "type": "bool" }, { "internalType": "contract ISuperfluidPool", "name": "pool", "type": "address" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "contract ISuperfluidPool", "name": "pool", "type": "address" }, { "internalType": "bytes", "name": "userData", "type": "bytes" } ], "name": "disconnectPool", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "contract ISuperfluidToken", "name": "token", "type": "address" }, { "internalType": "address", "name": "from", "type": "address" }, { "internalType": "contract ISuperfluidPool", "name": "pool", "type": "address" }, { "internalType": "uint256", "name": "requestedAmount", "type": "uint256" }, { "internalType": "bytes", "name": "userData", "type": "bytes" } ], "name": "distribute", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "contract ISuperfluidToken", "name": "token", "type": "address" }, { "internalType": "address", "name": "from", "type": "address" }, { "internalType": "contract ISuperfluidPool", "name": "pool", "type": "address" }, { "internalType": "int96", "name": "requestedFlowRate", "type": "int96" }, { "internalType": "bytes", "name": "userData", "type": "bytes" } ], "name": "distributeFlow", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "contract ISuperfluidToken", "name": "token", "type": "address" }, { "internalType": "address", "name": "from", "type": "address" }, { "internalType": "contract ISuperfluidPool", "name": "to", "type": "address" }, { "internalType": "uint256", "name": "requestedAmount", "type": "uint256" } ], "name": "estimateDistributionActualAmount", "outputs": [ { "internalType": "uint256", "name": "actualAmount", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "contract ISuperfluidToken", "name": "token", "type": "address" }, { "internalType": "address", "name": "from", "type": "address" }, { "internalType": "contract ISuperfluidPool", "name": "to", "type": "address" }, { "internalType": "int96", "name": "requestedFlowRate", "type": "int96" } ], "name": "estimateFlowDistributionActualFlowRate", "outputs": [ { "internalType": "int96", "name": "actualFlowRate", "type": "int96" }, { "internalType": "int96", "name": "totalDistributionFlowRate", "type": "int96" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "contract ISuperfluidToken", "name": "token", "type": "address" }, { "internalType": "address", "name": "from", "type": "address" }, { "internalType": "contract ISuperfluidPool", "name": "to", "type": "address" } ], "name": "getFlowDistributionFlowRate", "outputs": [{ "internalType": "int96", "name": "", "type": "int96" }], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "contract ISuperfluidToken", "name": "token", "type": "address" }, { "internalType": "address", "name": "account", "type": "address" } ], "name": "getNetFlow", "outputs": [{ "internalType": "int96", "name": "", "type": "int96" }], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "contract ISuperfluidPool", "name": "pool", "type": "address" } ], "name": "getPoolAdjustmentFlowInfo", "outputs": [ { "internalType": "address", "name": "", "type": "address" }, { "internalType": "bytes32", "name": "", "type": "bytes32" }, { "internalType": "int96", "name": "", "type": "int96" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "pool", "type": "address" } ], "name": "getPoolAdjustmentFlowRate", "outputs": [{ "internalType": "int96", "name": "", "type": "int96" }], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "contract ISuperfluidPool", "name": "pool", "type": "address" }, { "internalType": "address", "name": "member", "type": "address" } ], "name": "isMemberConnected", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "contract ISuperfluidToken", "name": "token", "type": "address" }, { "internalType": "address", "name": "account", "type": "address" } ], "name": "isPool", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "contract ISuperfluidPool", "name": "pool", "type": "address" }, { "internalType": "address", "name": "memberAddress", "type": "address" }, { "internalType": "uint128", "name": "newUnits", "type": "uint128" }, { "internalType": "bytes", "name": "userData", "type": "bytes" } ], "name": "updateMemberUnits", "outputs": [{ "internalType": "bool", "name": "success", "type": "bool" }], "stateMutability": "nonpayable", "type": "function" } ]
\_gda[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#_gda "Direct link to _gda")
---------------------------------------------------------------------------------------------------------
contract IGeneralDistributionAgreementV1 _gda
Fn constructor[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#fn-constructor "Direct link to Fn constructor")
--------------------------------------------------------------------------------------------------------------------------------------
function constructor( contract ISuperfluid host) public
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#parameters "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `host` | contract ISuperfluid | |
Fn createPool[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#fn-createpool "Direct link to Fn createPool")
-----------------------------------------------------------------------------------------------------------------------------------
_Creates a new Superfluid Pool._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#parameters-1 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperfluidToken | The Super Token address. |
| `admin` | address | The pool admin address. |
| `config` | struct PoolConfig | The pool configuration (see PoolConfig in IGeneralDistributionAgreementV1.sol) |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#return-values "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `success` | bool | A boolean value indicating whether the pool was created successfully. |
| `pool` | contract ISuperfluidPool | The address of the deployed Superfluid Pool |
Fn updateMemberUnits[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#fn-updatememberunits "Direct link to Fn updateMemberUnits")
--------------------------------------------------------------------------------------------------------------------------------------------------------
_Updates the units of a pool member._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#parameters-2 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `pool` | contract ISuperfluidPool | The Superfluid Pool to update. |
| `memberAddress` | address | The address of the member to update. |
| `newUnits` | uint128 | The new units of the member. |
| `userData` | bytes | User-specific data. |
Fn claimAll[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#fn-claimall "Direct link to Fn claimAll")
-----------------------------------------------------------------------------------------------------------------------------
_Claims all tokens from the pool._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#parameters-3 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `pool` | contract ISuperfluidPool | The Superfluid Pool to claim from. |
| `memberAddress` | address | The address of the member to claim for. |
| `userData` | bytes | User-specific data. |
Fn connectPool[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#fn-connectpool "Direct link to Fn connectPool")
--------------------------------------------------------------------------------------------------------------------------------------
_Connects a pool member to `pool`._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#parameters-4 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `pool` | contract ISuperfluidPool | The Superfluid Pool to connect. |
| `userData` | bytes | User-specific data. |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#return-values-1 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | bool | A boolean value indicating whether the connection was successful. |
Fn disconnectPool[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#fn-disconnectpool "Direct link to Fn disconnectPool")
-----------------------------------------------------------------------------------------------------------------------------------------------
_Disconnects a pool member from `pool`._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#parameters-5 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `pool` | contract ISuperfluidPool | The Superfluid Pool to disconnect. |
| `userData` | bytes | User-specific data. |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#return-values-2 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | bool | A boolean value indicating whether the disconnection was successful. |
Fn distribute[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#fn-distribute "Direct link to Fn distribute")
-----------------------------------------------------------------------------------------------------------------------------------
_Tries to distribute `requestedAmount` amount of `token` from `from` to `pool`._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#parameters-6 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperfluidToken | The Super Token address. |
| `from` | address | The address from which to distribute tokens. |
| `pool` | contract ISuperfluidPool | The Superfluid Pool address. |
| `requestedAmount` | uint256 | The amount of tokens to distribute. |
| `userData` | bytes | User-specific data. |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#return-values-3 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | bool | A boolean value indicating whether the distribution was successful. |
Fn distributeFlow[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#fn-distributeflow "Direct link to Fn distributeFlow")
-----------------------------------------------------------------------------------------------------------------------------------------------
_Tries to distribute flow at `requestedFlowRate` of `token` from `from` to `pool`._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#parameters-7 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperfluidToken | The Super Token address. |
| `from` | address | The address from which to distribute tokens. |
| `pool` | contract ISuperfluidPool | The Superfluid Pool address. |
| `requestedFlowRate` | int96 | The flow rate of tokens to distribute. |
| `userData` | bytes | User-specific data. |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#return-values-4 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | bool | A boolean value indicating whether the distribution was successful. |
Fn isPool[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#fn-ispool "Direct link to Fn isPool")
-----------------------------------------------------------------------------------------------------------------------
_Checks if the specified account is a pool._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#parameters-8 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperfluidToken | The Super Token address. |
| `account` | address | The account address to check. |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#return-values-5 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | bool | A boolean value indicating whether the account is a pool. |
Fn getNetFlow[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#fn-getnetflow "Direct link to Fn getNetFlow")
-----------------------------------------------------------------------------------------------------------------------------------
_Gets the GDA net flow rate for the specified account._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#parameters-9 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperfluidToken | The Super Token address. |
| `account` | address | The account address. |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#return-values-6 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | int96 | The gda net flow rate for the account. |
Fn getFlowDistributionFlowRate[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#fn-getflowdistributionflowrate "Direct link to Fn getFlowDistributionFlowRate")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
_Gets the flow rate of tokens between the specified accounts._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#parameters-10 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperfluidToken | The Super Token address. |
| `from` | address | The sender address. |
| `to` | contract ISuperfluidPool | The receiver address (the pool address). |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#return-values-7 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | int96 | The flow distribution flow rate |
Fn getPoolAdjustmentFlowRate[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#fn-getpooladjustmentflowrate "Direct link to Fn getPoolAdjustmentFlowRate")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
_Gets the pool adjustment flow rate for the specified pool._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#parameters-11 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `pool` | address | The pool address. |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#return-values-8 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | int96 | The pool adjustment flow rate. |
Fn estimateFlowDistributionActualFlowRate[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#fn-estimateflowdistributionactualflowrate "Direct link to Fn estimateFlowDistributionActualFlowRate")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
_Estimates the actual flow rate for flow distribution to the specified pool._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#parameters-12 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperfluidToken | The Super Token address. |
| `from` | address | The sender address. |
| `to` | contract ISuperfluidPool | The pool address. |
| `requestedFlowRate` | int96 | The requested flow rate. |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#return-values-9 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `actualFlowRate` | int96 | |
| `totalDistributionFlowRate` | int96 | |
Fn estimateDistributionActualAmount[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#fn-estimatedistributionactualamount "Direct link to Fn estimateDistributionActualAmount")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
_Estimates the actual amount for distribution to the specified pool._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#parameters-13 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperfluidToken | The Super Token address. |
| `from` | address | The sender address. |
| `to` | contract ISuperfluidPool | The pool address. |
| `requestedAmount` | uint256 | The requested amount. |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#return-values-10 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `actualAmount` | uint256 | The actual amount for distribution. |
Fn isMemberConnected[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#fn-ismemberconnected "Direct link to Fn isMemberConnected")
--------------------------------------------------------------------------------------------------------------------------------------------------------
_Checks if the specified member is connected to the pool._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#parameters-14 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `pool` | contract ISuperfluidPool | The Superfluid Pool address. |
| `member` | address | The member address. |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#return-values-11 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | bool | A boolean value indicating whether the member is connected to the pool. |
Fn getPoolAdjustmentFlowInfo[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#fn-getpooladjustmentflowinfo "Direct link to Fn getPoolAdjustmentFlowInfo")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
_Gets the pool adjustment flow information for the specified pool._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#parameters-15 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `pool` | contract ISuperfluidPool | The pool address. |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#return-values-12 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | address | The pool admin, pool ID, and pool adjustment flow rate. |
| `[1]` | bytes32 | |
| `[2]` | int96 | |
* [Contract Address](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#contract-address)
* [ABI](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#abi)
* [\_gda](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#_gda)
* [Fn constructor](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#fn-constructor)
* [Fn createPool](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#fn-createpool)
* [Fn updateMemberUnits](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#fn-updatememberunits)
* [Fn claimAll](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#fn-claimall)
* [Fn connectPool](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#fn-connectpool)
* [Fn disconnectPool](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#fn-disconnectpool)
* [Fn distribute](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#fn-distribute)
* [Fn distributeFlow](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#fn-distributeflow)
* [Fn isPool](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#fn-ispool)
* [Fn getNetFlow](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#fn-getnetflow)
* [Fn getFlowDistributionFlowRate](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#fn-getflowdistributionflowrate)
* [Fn getPoolAdjustmentFlowRate](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#fn-getpooladjustmentflowrate)
* [Fn estimateFlowDistributionActualFlowRate](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#fn-estimateflowdistributionactualflowrate)
* [Fn estimateDistributionActualAmount](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#fn-estimatedistributionactualamount)
* [Fn isMemberConnected](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#fn-ismemberconnected)
* [Fn getPoolAdjustmentFlowInfo](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder#fn-getpooladjustmentflowinfo)
---
# Using the SuperTokenV1Library | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/protocol/super-tokens/guides/using-library#__docusaurus_skipToContent_fallback)
On this page
The [SuperTokenV1Library](https://github.com/superfluid-finance/protocol-monorepo/blob/dev/packages/ethereum-contracts/contracts/apps/SuperTokenV1Library.sol)
is the primary interface for developers to interact with the Superfluid protocol when building smart contracts on-chain.
This comprehensive library provides all the necessary tools to work with the two main primitives of the Superfluid protocol: [Money Streaming](https://docs.superfluid.org/docs/protocol/money-streaming/overview)
(also called _Constant Flow Agreement_ or _CFA_) and [Distribution Pools](https://docs.superfluid.org/docs/protocol/distributions/overview)
(also called _General Distributions Agreement_ or _GDA_).
Getting Started[](https://docs.superfluid.org/docs/protocol/super-tokens/guides/using-library#getting-started "Direct link to Getting Started")
-------------------------------------------------------------------------------------------------------------------------------------------------
To use the SuperTokenV1Library in your smart contract, follow these steps:
1. Import the library in your contract:
import "@superfluid-finance/ethereum-contracts/contracts/apps/SuperTokenV1Library.sol";
2. Include the `using` statement in your contract:
using SuperTokenV1Library for ISuperToken;
about Native Super Tokens
For Native Super Tokens, use `using SuperTokenV1Library for ISETH;` instead.
Technical Reference
For more details on the full list of functions and usage, refer to the [SuperTokenV1Library Technical Reference](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library)
.
Key Concepts[](https://docs.superfluid.org/docs/protocol/super-tokens/guides/using-library#key-concepts "Direct link to Key Concepts")
----------------------------------------------------------------------------------------------------------------------------------------
The SuperTokenV1Library revolves around two main primitives:
1. **Constant Flow Agreement (CFA)**: This represents Money Streaming functionality.
2. **General Distributions Agreement (GDA)**: This handles Distribution Pools.
The library provides functions for various operations within these primitives:
* Writing to the protocol (e.g., creating flows, updating flows, creating pools)
* Reading from the protocol (e.g., getting flow rates)
* Access control (allowing other wallets to control flow rates)
* Attaching user data to blockchain function calls
Key Functions[](https://docs.superfluid.org/docs/protocol/super-tokens/guides/using-library#key-functions "Direct link to Key Functions")
-------------------------------------------------------------------------------------------------------------------------------------------
Let's explore some example functions in the SuperTokenV1Library:
### Money Streaming (CFA) Functions[](https://docs.superfluid.org/docs/protocol/super-tokens/guides/using-library#money-streaming-cfa-functions "Direct link to Money Streaming (CFA) Functions")
The library provides a wide range of functions for managing money streams, including creating, updating, and deleting flows. For example:
#### Creating a Flow[](https://docs.superfluid.org/docs/protocol/super-tokens/guides/using-library#creating-a-flow "Direct link to Creating a Flow")
function createFlow( ISuperToken token, address receiver, int96 flowRate, bytes memory userData) internal returns (bool)
This function creates a new money stream. You can omit the `userData` parameter if not needed.
#### Getting Flow Information[](https://docs.superfluid.org/docs/protocol/super-tokens/guides/using-library#getting-flow-information "Direct link to Getting Flow Information")
function getFlowInfo( ISuperToken token, address sender, address receiver) internal returns ( uint256 lastUpdated, int96 flowRate, uint256 deposit, uint256 owedDeposit)
This function retrieves detailed information about a specific flow.
### Distribution Pools (GDA) Functions[](https://docs.superfluid.org/docs/protocol/super-tokens/guides/using-library#distribution-pools-gda-functions "Direct link to Distribution Pools (GDA) Functions")
By the same token, the library provides functions for managing distribution pools, including creating pools and claiming distributions:
#### Creating a Pool[](https://docs.superfluid.org/docs/protocol/super-tokens/guides/using-library#creating-a-pool "Direct link to Creating a Pool")
function createPool( contract ISuperToken token, address admin, struct PoolConfig poolConfig) internal returns (contract ISuperfluidPool pool)
The `PoolConfig` struct is defined as follows:
struct PoolConfig { bool transferabilityForUnitsOwner; bool distributionFromAnyAddress;}
* `transferabilityForUnitsOwner`: If true, the pool members can transfer their owned units, else, only the pool admin can manipulate the units for pool members
* `distributionFromAnyAddress`: If true, anyone can execute distributions via the pool, else, only the pool admin can execute distributions via the pool
#### Claiming tokens[](https://docs.superfluid.org/docs/protocol/super-tokens/guides/using-library#claiming-tokens "Direct link to Claiming tokens")
function claimAll( contract ISuperToken token, contract ISuperfluidPool pool, address memberAddress) internal returns (bool)
This function allows a member to claim all tokens to all the members of the pool.
### Access Control Functions[](https://docs.superfluid.org/docs/protocol/super-tokens/guides/using-library#access-control-functions "Direct link to Access Control Functions")
The library also provides functions for managing access control and permissions between different wallet addresses and smart contracts:
#### Setting Flow Permissions[](https://docs.superfluid.org/docs/protocol/super-tokens/guides/using-library#setting-flow-permissions "Direct link to Setting Flow Permissions")
function setFlowPermissions( ISuperToken token, address flowOperator, bool allowCreate, bool allowUpdate, bool allowDelete, int96 flowRateAllowance) internal returns (bool)
This function allows you to grant specific permissions to another address (flowOperator) to manage flows on your behalf.
Advanced Usage[](https://docs.superfluid.org/docs/protocol/super-tokens/guides/using-library#advanced-usage "Direct link to Advanced Usage")
----------------------------------------------------------------------------------------------------------------------------------------------
### Context-Aware Functions[](https://docs.superfluid.org/docs/protocol/super-tokens/guides/using-library#context-aware-functions "Direct link to Context-Aware Functions")
For more advanced use cases including with [Super Apps](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/understand-super-apps)
, the library provides context-aware versions of many functions. These are useful when you need to chain multiple operations or when working within the context of a Superfluid callback:
function createFlowFromWithCtx( ISuperToken token, address sender, address receiver, int96 flowRate, bytes memory ctx) internal returns (bytes memory newCtx)
### User Data[](https://docs.superfluid.org/docs/protocol/super-tokens/guides/using-library#user-data "Direct link to User Data")
Many functions in the SuperTokenV1Library allow you to attach user data to your transactions. This can be useful for adding metadata or triggering specific logic in receiver contracts.
Best Practices[](https://docs.superfluid.org/docs/protocol/super-tokens/guides/using-library#best-practices "Direct link to Best Practices")
----------------------------------------------------------------------------------------------------------------------------------------------
1. Always check return values of functions to ensure operations were successful.
2. Be mindful of gas costs, especially when working with multiple flows or large distribution pools.
3. Use the appropriate permissions and access control functions to ensure the security of your contract.
Conclusion[](https://docs.superfluid.org/docs/protocol/super-tokens/guides/using-library#conclusion "Direct link to Conclusion")
----------------------------------------------------------------------------------------------------------------------------------
The SuperTokenV1Library is a powerful tool for interacting with the Superfluid protocol on-chain, in order to build smart contracts. By leveraging its functions for money streaming and distribution pools, you can create sophisticated blockchain applications with real-time finance capabilities. Always refer to the latest documentation and test thoroughly to ensure your implementation is correct and secure.
* [Getting Started](https://docs.superfluid.org/docs/protocol/super-tokens/guides/using-library#getting-started)
* [Key Concepts](https://docs.superfluid.org/docs/protocol/super-tokens/guides/using-library#key-concepts)
* [Key Functions](https://docs.superfluid.org/docs/protocol/super-tokens/guides/using-library#key-functions)
* [Money Streaming (CFA) Functions](https://docs.superfluid.org/docs/protocol/super-tokens/guides/using-library#money-streaming-cfa-functions)
* [Distribution Pools (GDA) Functions](https://docs.superfluid.org/docs/protocol/super-tokens/guides/using-library#distribution-pools-gda-functions)
* [Access Control Functions](https://docs.superfluid.org/docs/protocol/super-tokens/guides/using-library#access-control-functions)
* [Advanced Usage](https://docs.superfluid.org/docs/protocol/super-tokens/guides/using-library#advanced-usage)
* [Context-Aware Functions](https://docs.superfluid.org/docs/protocol/super-tokens/guides/using-library#context-aware-functions)
* [User Data](https://docs.superfluid.org/docs/protocol/super-tokens/guides/using-library#user-data)
* [Best Practices](https://docs.superfluid.org/docs/protocol/super-tokens/guides/using-library#best-practices)
* [Conclusion](https://docs.superfluid.org/docs/protocol/super-tokens/guides/using-library#conclusion)
---
# SuperTokenV1Library | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#__docusaurus_skipToContent_fallback)
On this page
**Library for Token Centric Interface**
The `SuperTokenV1Library` is a solidity library that allows you to interact with the Superfluid Protocol. It is a comprehensive library for Superfluid protocol. It includes all the functions that are required to interact with the Superfluid protocol. It includes functions for interacting with Money Streaming and Distributions. In order to have access to the library, you need to:
* Import the library in your contract as such:
`import "@superfluid-finance/ethereum-contracts/contracts/apps/SuperTokenV1Library.sol";`
* Make sure that you include the `using` statement in your contract:
`using SuperTokenV1Library for ISuperToken;`
Note 1
In the case of interacting with Native Super Tokens you should use `using SuperTokenV1Library for ISETH;` instead.
Note 2
It is important to "warm up" the cache and cache the `host`, `cfa`, `gda` before calling, this is only applicable to Foundry tests where the vm.expectRevert() will not work as expected. You must use vm.startPrank(account) instead of vm.prank when executing functions if the cache isn't "warmed up" yet. vm.prank impersonates the account only for the first call, which will be used for caching.
Fn flowX[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-flowx "Direct link to Fn flowX")
-------------------------------------------------------------------------------------------------------------------------
function flowX( contract ISuperToken token, address receiverOrPool, int96 flowRate) internal returns (bool)
_creates a flow to an account or to pool members. If the receiver is an account, it uses the CFA, if it's a pool it uses the GDA._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | Super token address |
| `receiverOrPool` | address | The receiver (account) or pool |
| `flowRate` | int96 | the flowRate to be set. |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | bool | A boolean value indicating whether the operation was successful. |
| Note that all the specifics of the underlying agreement used still apply. | | |
| E.g. if the GDA is used, the effective flowRate may differ from the selected one. | | |
Fn transferX[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-transferx "Direct link to Fn transferX")
-------------------------------------------------------------------------------------------------------------------------------------
function transferX( contract ISuperToken token, address receiverOrPool, uint256 amount) internal returns (bool)
_transfers `amount` to an account or distributes it to pool members._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-1 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | Super token address |
| `receiverOrPool` | address | The receiver (account) or pool |
| `amount` | uint256 | the amount to be transferred/distributed |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-1 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | bool | A boolean value indicating whether the operation was successful. |
| Note in case of distribution, the effective amount may be smaller than requested. | | |
Fn getFlowRate[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-getflowrate "Direct link to Fn getFlowRate")
-------------------------------------------------------------------------------------------------------------------------------------------
function getFlowRate( contract ISuperToken token, address sender, address receiverOrPool) internal returns (int96 flowRate)
_get flow rate between two accounts for given token_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-2 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token used in flow |
| `sender` | address | The sender of the flow |
| `receiverOrPool` | address | The receiver or pool receiving or distributing the flow |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-2 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `flowRate` | int96 | The flow rate |
| Note: edge case: if a CFA stream is going to a pool, it will return 0. | | |
Fn getFlowInfo[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-getflowinfo "Direct link to Fn getFlowInfo")
-------------------------------------------------------------------------------------------------------------------------------------------
function getFlowInfo( contract ISuperToken token, address sender, address receiverOrPool) internal returns (uint256 lastUpdated, int96 flowRate, uint256 deposit, uint256 owedDeposit)
_get flow info between an account and another account or pool for given token_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-3 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token used in flow |
| `sender` | address | The sender of the flow |
| `receiverOrPool` | address | The receiver or pool receiving or distributing the flow |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-3 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `lastUpdated` | uint256 | Timestamp of flow creation or last flowrate change |
| `flowRate` | int96 | The flow rate |
| `deposit` | uint256 | The amount of deposit the flow |
| `owedDeposit` | uint256 | The amount of owed deposit of the flow |
| Note: edge case: a CFA stream going to a pool will not be "seen". | | |
Fn getNetFlowRate[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-getnetflowrate "Direct link to Fn getNetFlowRate")
----------------------------------------------------------------------------------------------------------------------------------------------------
function getNetFlowRate( contract ISuperToken token, address account) internal returns (int96 flowRate)
_get net flow rate for given account for given token (CFA + GDA)_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-4 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | Super token address |
| `account` | address | Account to query |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-4 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `flowRate` | int96 | The net flow rate of the account |
Fn getNetFlowInfo[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-getnetflowinfo "Direct link to Fn getNetFlowInfo")
----------------------------------------------------------------------------------------------------------------------------------------------------
function getNetFlowInfo( contract ISuperToken token, address account) internal returns (uint256 lastUpdated, int96 flowRate, uint256 deposit, uint256 owedDeposit)
_get the aggregated flow info of the account (CFA + GDA)_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-5 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | Super token address |
| `account` | address | Account to query |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-5 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `lastUpdated` | uint256 | Timestamp of the last change of the net flow |
| `flowRate` | int96 | The net flow rate of token for account |
| `deposit` | uint256 | The sum of all deposits for account's flows |
| `owedDeposit` | uint256 | The sum of all owed deposits for account's flows |
Fn getBufferAmountByFlowRate[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-getbufferamountbyflowrate "Direct link to Fn getBufferAmountByFlowRate")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function getBufferAmountByFlowRate( contract ISuperToken token, int96 flowRate) internal returns (uint256 bufferAmount)
_calculate buffer needed for a CFA flow with the given flowrate (for GDA, see 2nd notice below)_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-6 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token used in flow |
| `flowRate` | int96 | The flowrate to calculate the needed buffer for |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-6 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `bufferAmount` | uint256 | The buffer amount based on flowRate, liquidationPeriod and minimum deposit |
the returned amount is exact only for the scenario where no flow exists before. In order to get the buffer delta for a delta flowrate, you need to get the buffer amount for the new total flowrate and subtract the previous buffer. That's because there's not always linear proportionality between flowrate and buffer. for GDA flows, the required buffer is typically slightly lower. That's due to an implementation detail (round-up "clipping" to 64 bit in the CFA). The return value of this method is thus to be considered not a precise value, but a lower bound for GDA flows.
Fn flow[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-flow "Direct link to Fn flow")
----------------------------------------------------------------------------------------------------------------------
function flow( contract ISuperToken token, address receiver, int96 flowRate) internal returns (bool)
_Sets the given CFA flowrate between the caller and a given receiver. If there's no pre-existing flow and `flowRate` non-zero, a new flow is created. If there's an existing flow and `flowRate` non-zero, the flowRate of that flow is updated. If there's an existing flow and `flowRate` zero, the flow is deleted. If the existing and given flowRate are equal, no action is taken. On creation of a flow, a "buffer" amount is automatically detracted from the sender account's available balance. If the sender account is solvent when the flow is deleted, this buffer is redeemed to it._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-7 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | Super token address |
| `receiver` | address | The receiver of the flow |
| `flowRate` | int96 | The wanted flowrate in wad/second. Only positive values are valid here. |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-7 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | bool | bool |
Fn flow (with User Data)[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-flow-with-user-data "Direct link to Fn flow (with User Data)")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
function flow( contract ISuperToken token, address receiver, int96 flowRate, bytes userData) internal returns (bool)
_Set CFA flowrate with userData_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-8 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | Super token address |
| `receiver` | address | The receiver of the flow |
| `flowRate` | int96 | The wanted flowrate in wad/second. Only positive values are valid here. |
| `userData` | bytes | The userdata passed along with call |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-8 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | bool | bool |
Fn createFlow[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-createflow "Direct link to Fn createFlow")
----------------------------------------------------------------------------------------------------------------------------------------
function createFlow( contract ISuperToken token, address receiver, int96 flowRate) internal returns (bool)
_Create flow without userData_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-9 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token used in flow |
| `receiver` | address | The receiver of the flow |
| `flowRate` | int96 | The desired flowRate |
Fn createFlow (with User Data)[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-createflow-with-user-data "Direct link to Fn createFlow (with User Data)")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function createFlow( contract ISuperToken token, address receiver, int96 flowRate, bytes userData) internal returns (bool)
_Create flow with userData_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-10 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token used in flow |
| `receiver` | address | The receiver of the flow |
| `flowRate` | int96 | The desired flowRate |
| `userData` | bytes | The userdata passed along with call |
Fn updateFlow[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-updateflow "Direct link to Fn updateFlow")
----------------------------------------------------------------------------------------------------------------------------------------
function updateFlow( contract ISuperToken token, address receiver, int96 flowRate) internal returns (bool)
_Update flow without userData_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-11 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token used in flow |
| `receiver` | address | The receiver of the flow |
| `flowRate` | int96 | The desired flowRate |
Fn updateFlow (with User Data)[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-updateflow-with-user-data "Direct link to Fn updateFlow (with User Data)")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function updateFlow( contract ISuperToken token, address receiver, int96 flowRate, bytes userData) internal returns (bool)
_Update flow with userData_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-12 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token used in flow |
| `receiver` | address | The receiver of the flow |
| `flowRate` | int96 | The desired flowRate |
| `userData` | bytes | The userdata passed along with call |
Fn deleteFlow[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-deleteflow "Direct link to Fn deleteFlow")
----------------------------------------------------------------------------------------------------------------------------------------
function deleteFlow( contract ISuperToken token, address sender, address receiver) internal returns (bool)
_Delete flow without userData_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-13 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token used in flow |
| `sender` | address | The sender of the flow |
| `receiver` | address | The receiver of the flow |
Fn deleteFlow (with User Data)[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-deleteflow-with-user-data "Direct link to Fn deleteFlow (with User Data)")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function deleteFlow( contract ISuperToken token, address sender, address receiver, bytes userData) internal returns (bool)
_Delete flow with userData_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-14 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token used in flow |
| `sender` | address | The sender of the flow |
| `receiver` | address | The receiver of the flow |
| `userData` | bytes | The userdata passed along with call |
Fn flowFrom[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-flowfrom "Direct link to Fn flowFrom")
----------------------------------------------------------------------------------------------------------------------------------
function flowFrom( contract ISuperToken token, address sender, address receiver, int96 flowRate) internal returns (bool)
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-15 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | Super token address |
| `sender` | address | The sender of the flow |
| `receiver` | address | The receiver of the flow |
| `flowRate` | int96 | The wanted flowRate in wad/second. Only positive values are valid here. |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-9 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | bool | bool |
Like `flow`, but can be invoked by an account with flowOperator permissions on behalf of the sender account.
Fn flowFrom (with User Data)[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-flowfrom-with-user-data "Direct link to Fn flowFrom (with User Data)")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function flowFrom( contract ISuperToken token, address sender, address receiver, int96 flowRate, bytes userData) internal returns (bool)
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-16 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | Super token address |
| `sender` | address | The sender of the flow |
| `receiver` | address | The receiver of the flow |
| `flowRate` | int96 | The wanted flowRate in wad/second. Only positive values are valid here. |
| `userData` | bytes | The userdata passed along with call |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-10 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | bool | bool |
Like `flowFrom`, but takes userData
Fn setFlowPermissions[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-setflowpermissions "Direct link to Fn setFlowPermissions")
----------------------------------------------------------------------------------------------------------------------------------------------------------------
function setFlowPermissions( contract ISuperToken token, address flowOperator, bool allowCreate, bool allowUpdate, bool allowDelete, int96 flowRateAllowance) internal returns (bool)
_Update permissions for flow operator_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-17 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token used in flow |
| `flowOperator` | address | The address given flow permissions |
| `allowCreate` | bool | creation permissions |
| `allowUpdate` | bool | |
| `allowDelete` | bool | |
| `flowRateAllowance` | int96 | The allowance provided to flowOperator |
Fn setMaxFlowPermissions[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-setmaxflowpermissions "Direct link to Fn setMaxFlowPermissions")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function setMaxFlowPermissions( contract ISuperToken token, address flowOperator) internal returns (bool)
_Update permissions for flow operator - give operator max permissions_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-18 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token used in flow |
| `flowOperator` | address | The address given flow permissions |
Fn revokeFlowPermissions[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-revokeflowpermissions "Direct link to Fn revokeFlowPermissions")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function revokeFlowPermissions( contract ISuperToken token, address flowOperator) internal returns (bool)
_Update permissions for flow operator - revoke all permission_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-19 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token used in flow |
| `flowOperator` | address | The address given flow permissions |
Fn increaseFlowRateAllowance[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-increaseflowrateallowance "Direct link to Fn increaseFlowRateAllowance")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function increaseFlowRateAllowance( contract ISuperToken token, address flowOperator, int96 addedFlowRateAllowance) internal returns (bool)
_Increases the flow rate allowance for flow operator_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-20 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token used in flow |
| `flowOperator` | address | The address whose flow rate allowance is increased |
| `addedFlowRateAllowance` | int96 | amount to increase allowance by |
allowing userData to be a parameter here triggered stack too deep error
Fn increaseFlowRateAllowance (with User Data)[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-increaseflowrateallowance-with-user-data "Direct link to Fn increaseFlowRateAllowance (with User Data)")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function increaseFlowRateAllowance( contract ISuperToken token, address flowOperator, int96 addedFlowRateAllowance, bytes userData) internal returns (bool)
_Increases the flow rate allowance for flow operator_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-21 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token used in flow |
| `flowOperator` | address | The address whose flow rate allowance is increased |
| `addedFlowRateAllowance` | int96 | amount to increase allowance by |
| `userData` | bytes | The userdata passed along with call |
allowing userData to be a parameter here triggered stack too deep error
Fn decreaseFlowRateAllowance[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-decreaseflowrateallowance "Direct link to Fn decreaseFlowRateAllowance")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function decreaseFlowRateAllowance( contract ISuperToken token, address flowOperator, int96 subtractedFlowRateAllowance) internal returns (bool)
_Decreases the flow rate allowance for flow operator_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-22 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token used in flow |
| `flowOperator` | address | The address whose flow rate allowance is decreased |
| `subtractedFlowRateAllowance` | int96 | amount to decrease allowance by |
allowing userData to be a parameter here triggered stack too deep error
Fn decreaseFlowRateAllowance (with User Data)[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-decreaseflowrateallowance-with-user-data "Direct link to Fn decreaseFlowRateAllowance (with User Data)")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function decreaseFlowRateAllowance( contract ISuperToken token, address flowOperator, int96 subtractedFlowRateAllowance, bytes userData) internal returns (bool)
_Decreases the flow rate allowance for flow operator_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-23 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token used in flow |
| `flowOperator` | address | The address whose flow rate allowance is decreased |
| `subtractedFlowRateAllowance` | int96 | amount to decrease allowance by |
| `userData` | bytes | The userdata passed along with call |
allowing userData to be a parameter here triggered stack too deep error
Fn increaseFlowRateAllowanceWithPermissions[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-increaseflowrateallowancewithpermissions "Direct link to Fn increaseFlowRateAllowanceWithPermissions")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function increaseFlowRateAllowanceWithPermissions( contract ISuperToken token, address flowOperator, uint8 permissionsToAdd, int96 addedFlowRateAllowance) internal returns (bool)
_Increases the flow rate allowance for flow operator and adds the permissions_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-24 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token used in flow |
| `flowOperator` | address | The address whose flow rate allowance is increased |
| `permissionsToAdd` | uint8 | The permissions to add for the flow operator |
| `addedFlowRateAllowance` | int96 | amount to increase allowance by |
allowing userData to be a parameter here triggered stack too deep error
Fn increaseFlowRateAllowanceWithPermissions (with User Data)[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-increaseflowrateallowancewithpermissions-with-user-data "Direct link to Fn increaseFlowRateAllowanceWithPermissions (with User Data)")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function increaseFlowRateAllowanceWithPermissions( contract ISuperToken token, address flowOperator, uint8 permissionsToAdd, int96 addedFlowRateAllowance, bytes userData) internal returns (bool)
_Increases the flow rate allowance for flow operator and adds the permissions_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-25 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token used in flow |
| `flowOperator` | address | The address whose flow rate allowance is increased |
| `permissionsToAdd` | uint8 | The permissions to add for the flow operator |
| `addedFlowRateAllowance` | int96 | amount to increase allowance by |
| `userData` | bytes | The userdata passed along with call |
allowing userData to be a parameter here triggered stack too deep error
Fn decreaseFlowRateAllowanceWithPermissions[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-decreaseflowrateallowancewithpermissions "Direct link to Fn decreaseFlowRateAllowanceWithPermissions")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function decreaseFlowRateAllowanceWithPermissions( contract ISuperToken token, address flowOperator, uint8 permissionsToRemove, int96 subtractedFlowRateAllowance) internal returns (bool)
_Decreases the flow rate allowance for flow operator and removes the permissions_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-26 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token used in flow |
| `flowOperator` | address | The address whose flow rate allowance is subtracted |
| `permissionsToRemove` | uint8 | The permissions to remove for the flow operator |
| `subtractedFlowRateAllowance` | int96 | amount to subtract allowance by |
allowing userData to be a parameter here triggered stack too deep error
Fn decreaseFlowRateAllowanceWithPermissions (with User Data)[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-decreaseflowrateallowancewithpermissions-with-user-data "Direct link to Fn decreaseFlowRateAllowanceWithPermissions (with User Data)")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function decreaseFlowRateAllowanceWithPermissions( contract ISuperToken token, address flowOperator, uint8 permissionsToRemove, int96 subtractedFlowRateAllowance, bytes userData) internal returns (bool)
_Decreases the flow rate allowance for flow operator and removes the permissions_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-27 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token used in flow |
| `flowOperator` | address | The address whose flow rate allowance is subtracted |
| `permissionsToRemove` | uint8 | The permissions to remove for the flow operator |
| `subtractedFlowRateAllowance` | int96 | amount to subtract allowance by |
| `userData` | bytes | The userdata passed along with call |
allowing userData to be a parameter here triggered stack too deep error
Fn createFlowFrom[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-createflowfrom "Direct link to Fn createFlowFrom")
----------------------------------------------------------------------------------------------------------------------------------------------------
function createFlowFrom( contract ISuperToken token, address sender, address receiver, int96 flowRate) internal returns (bool)
_Creates flow as an operator without userData_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-28 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token to flow |
| `sender` | address | The sender of the flow |
| `receiver` | address | The receiver of the flow |
| `flowRate` | int96 | The desired flowRate |
Fn createFlowFrom (with User Data)[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-createflowfrom-with-user-data "Direct link to Fn createFlowFrom (with User Data)")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function createFlowFrom( contract ISuperToken token, address sender, address receiver, int96 flowRate, bytes userData) internal returns (bool)
_Creates flow as an operator with userData_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-29 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token to flow |
| `sender` | address | The sender of the flow |
| `receiver` | address | The receiver of the flow |
| `flowRate` | int96 | The desired flowRate |
| `userData` | bytes | The user provided data |
Fn updateFlowFrom[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-updateflowfrom "Direct link to Fn updateFlowFrom")
----------------------------------------------------------------------------------------------------------------------------------------------------
function updateFlowFrom( contract ISuperToken token, address sender, address receiver, int96 flowRate) internal returns (bool)
_Updates flow as an operator without userData_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-30 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token to flow |
| `sender` | address | The sender of the flow |
| `receiver` | address | The receiver of the flow |
| `flowRate` | int96 | The desired flowRate |
Fn updateFlowFrom (with User Data)[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-updateflowfrom-with-user-data "Direct link to Fn updateFlowFrom (with User Data)")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function updateFlowFrom( contract ISuperToken token, address sender, address receiver, int96 flowRate, bytes userData) internal returns (bool)
_Updates flow as an operator with userData_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-31 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token to flow |
| `sender` | address | The sender of the flow |
| `receiver` | address | The receiver of the flow |
| `flowRate` | int96 | The desired flowRate |
| `userData` | bytes | The user provided data |
Fn deleteFlowFrom[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-deleteflowfrom "Direct link to Fn deleteFlowFrom")
----------------------------------------------------------------------------------------------------------------------------------------------------
function deleteFlowFrom( contract ISuperToken token, address sender, address receiver) internal returns (bool)
_Deletes flow as an operator without userData_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-32 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token to flow |
| `sender` | address | The sender of the flow |
| `receiver` | address | The receiver of the flow |
Fn deleteFlowFrom (with User Data)[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-deleteflowfrom-with-user-data "Direct link to Fn deleteFlowFrom (with User Data)")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function deleteFlowFrom( contract ISuperToken token, address sender, address receiver, bytes userData) internal returns (bool)
_Deletes flow as an operator with userData_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-33 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token to flow |
| `sender` | address | The sender of the flow |
| `receiver` | address | The receiver of the flow |
| `userData` | bytes | The user provided data |
Fn createFlowWithCtx[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-createflowwithctx "Direct link to Fn createFlowWithCtx")
-------------------------------------------------------------------------------------------------------------------------------------------------------------
function createFlowWithCtx( contract ISuperToken token, address receiver, int96 flowRate, bytes ctx) internal returns (bytes newCtx)
_Create flow with context and userData_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-34 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token to flow |
| `receiver` | address | The receiver of the flow |
| `flowRate` | int96 | The desired flowRate |
| `ctx` | bytes | Context bytes (see ISuperfluid.sol for Context struct) |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-11 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `newCtx` | bytes | The updated context after the execution of the agreement function |
Fn createFlowFromWithCtx[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-createflowfromwithctx "Direct link to Fn createFlowFromWithCtx")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function createFlowFromWithCtx( contract ISuperToken token, address sender, address receiver, int96 flowRate, bytes ctx) internal returns (bytes newCtx)
_Create flow by operator with context_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-35 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token to flow |
| `sender` | address | The sender of the flow |
| `receiver` | address | The receiver of the flow |
| `flowRate` | int96 | The desired flowRate |
| `ctx` | bytes | Context bytes (see ISuperfluid.sol for Context struct) |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-12 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `newCtx` | bytes | The updated context after the execution of the agreement function |
Fn updateFlowWithCtx[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-updateflowwithctx "Direct link to Fn updateFlowWithCtx")
-------------------------------------------------------------------------------------------------------------------------------------------------------------
function updateFlowWithCtx( contract ISuperToken token, address receiver, int96 flowRate, bytes ctx) internal returns (bytes newCtx)
_Update flow with context_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-36 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token to flow |
| `receiver` | address | The receiver of the flow |
| `flowRate` | int96 | The desired flowRate |
| `ctx` | bytes | Context bytes (see ISuperfluid.sol for Context struct) |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-13 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `newCtx` | bytes | The updated context after the execution of the agreement function |
Fn updateFlowFromWithCtx[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-updateflowfromwithctx "Direct link to Fn updateFlowFromWithCtx")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function updateFlowFromWithCtx( contract ISuperToken token, address sender, address receiver, int96 flowRate, bytes ctx) internal returns (bytes newCtx)
_Update flow by operator with context_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-37 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token to flow |
| `sender` | address | The receiver of the flow |
| `receiver` | address | The receiver of the flow |
| `flowRate` | int96 | The desired flowRate |
| `ctx` | bytes | Context bytes (see ISuperfluid.sol for Context struct) |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-14 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `newCtx` | bytes | The updated context after the execution of the agreement function |
Fn deleteFlowWithCtx[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-deleteflowwithctx "Direct link to Fn deleteFlowWithCtx")
-------------------------------------------------------------------------------------------------------------------------------------------------------------
function deleteFlowWithCtx( contract ISuperToken token, address sender, address receiver, bytes ctx) internal returns (bytes newCtx)
_Delete flow with context_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-38 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token to flow |
| `sender` | address | The sender of the flow |
| `receiver` | address | The receiver of the flow |
| `ctx` | bytes | Context bytes (see ISuperfluid.sol for Context struct) |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-15 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `newCtx` | bytes | The updated context after the execution of the agreement function |
Fn deleteFlowFromWithCtx[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-deleteflowfromwithctx "Direct link to Fn deleteFlowFromWithCtx")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function deleteFlowFromWithCtx( contract ISuperToken token, address sender, address receiver, bytes ctx) internal returns (bytes newCtx)
_Delete flow by operator with context_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-39 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token to flow |
| `sender` | address | The sender of the flow |
| `receiver` | address | The receiver of the flow |
| `ctx` | bytes | Context bytes (see ISuperfluid.sol for Context struct) |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-16 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `newCtx` | bytes | The updated context after the execution of the agreement function |
Fn setFlowPermissionsWithCtx[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-setflowpermissionswithctx "Direct link to Fn setFlowPermissionsWithCtx")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function setFlowPermissionsWithCtx( contract ISuperToken token, address flowOperator, bool allowCreate, bool allowUpdate, bool allowDelete, int96 flowRateAllowance, bytes ctx) internal returns (bytes newCtx)
_Update permissions for flow operator in callback_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-40 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token used in flow |
| `flowOperator` | address | The address given flow permissions |
| `allowCreate` | bool | creation permissions |
| `allowUpdate` | bool | |
| `allowDelete` | bool | |
| `flowRateAllowance` | int96 | The allowance provided to flowOperator |
| `ctx` | bytes | Context bytes (see ISuperfluid.sol for Context struct) |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-17 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `newCtx` | bytes | The updated context after the execution of the agreement function |
allowing userData to be a parameter here triggered stack too deep error
Fn setMaxFlowPermissionsWithCtx[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-setmaxflowpermissionswithctx "Direct link to Fn setMaxFlowPermissionsWithCtx")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function setMaxFlowPermissionsWithCtx( contract ISuperToken token, address flowOperator, bytes ctx) internal returns (bytes newCtx)
_Update permissions for flow operator - give operator max permissions_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-41 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token used in flow |
| `flowOperator` | address | The address given flow permissions |
| `ctx` | bytes | Context bytes (see ISuperfluid.sol for Context struct) |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-18 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `newCtx` | bytes | The updated context after the execution of the agreement function |
Fn revokeFlowPermissionsWithCtx[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-revokeflowpermissionswithctx "Direct link to Fn revokeFlowPermissionsWithCtx")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function revokeFlowPermissionsWithCtx( contract ISuperToken token, address flowOperator, bytes ctx) internal returns (bytes newCtx)
_Update permissions for flow operator - revoke all permission_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-42 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token used in flow |
| `flowOperator` | address | The address given flow permissions |
| `ctx` | bytes | Context bytes (see ISuperfluid.sol for Context struct) |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-19 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `newCtx` | bytes | The updated context after the execution of the agreement function |
Fn getCFAFlowRate[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-getcfaflowrate "Direct link to Fn getCFAFlowRate")
----------------------------------------------------------------------------------------------------------------------------------------------------
function getCFAFlowRate( contract ISuperToken token, address sender, address receiver) internal returns (int96 flowRate)
_get CFA flow rate between two accounts for given token_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-43 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token used in flow |
| `sender` | address | The sender of the flow |
| `receiver` | address | The receiver of the flow |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-20 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `flowRate` | int96 | The flow rate |
Fn getCFAFlowInfo[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-getcfaflowinfo "Direct link to Fn getCFAFlowInfo")
----------------------------------------------------------------------------------------------------------------------------------------------------
function getCFAFlowInfo( contract ISuperToken token, address sender, address receiver) internal returns (uint256 lastUpdated, int96 flowRate, uint256 deposit, uint256 owedDeposit)
_get CFA flow info between two accounts for given token_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-44 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token used in flow |
| `sender` | address | The sender of the flow |
| `receiver` | address | The receiver of the flow |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-21 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `lastUpdated` | uint256 | Timestamp of flow creation or last flowrate change |
| `flowRate` | int96 | The flow rate |
| `deposit` | uint256 | The amount of deposit the flow |
| `owedDeposit` | uint256 | The amount of owed deposit of the flow |
Fn getCFANetFlowRate[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-getcfanetflowrate "Direct link to Fn getCFANetFlowRate")
-------------------------------------------------------------------------------------------------------------------------------------------------------------
function getCFANetFlowRate( contract ISuperToken token, address account) internal returns (int96 flowRate)
_get CFA net flow rate for given account for given token_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-45 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | Super token address |
| `account` | address | Account to query |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-22 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `flowRate` | int96 | The net flow rate of the account |
Fn getCFANetFlowInfo[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-getcfanetflowinfo "Direct link to Fn getCFANetFlowInfo")
-------------------------------------------------------------------------------------------------------------------------------------------------------------
function getCFANetFlowInfo( contract ISuperToken token, address account) internal returns (uint256 lastUpdated, int96 flowRate, uint256 deposit, uint256 owedDeposit)
_get the aggregated CFA flow info of the account_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-46 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | Super token address |
| `account` | address | Account to query |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-23 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `lastUpdated` | uint256 | Timestamp of the last change of the net flow |
| `flowRate` | int96 | The net flow rate of token for account |
| `deposit` | uint256 | The sum of all deposits for account's flows |
| `owedDeposit` | uint256 | The sum of all owed deposits for account's flows |
Fn getFlowPermissions[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-getflowpermissions "Direct link to Fn getFlowPermissions")
----------------------------------------------------------------------------------------------------------------------------------------------------------------
function getFlowPermissions( contract ISuperToken token, address sender, address flowOperator) internal returns (bool allowCreate, bool allowUpdate, bool allowDelete, int96 flowRateAllowance)
_get existing CFA flow permissions_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-47 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token used in flow |
| `sender` | address | sender of a flow |
| `flowOperator` | address | the address we are checking permissions of for sender & token |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-24 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `allowCreate` | bool | is true if the flowOperator can create flows |
| `allowUpdate` | bool | is true if the flowOperator can update flows |
| `allowDelete` | bool | is true if the flowOperator can delete flows |
| `flowRateAllowance` | int96 | The flow rate allowance the flowOperator is granted (only goes down) |
Fn createPool[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-createpool "Direct link to Fn createPool")
----------------------------------------------------------------------------------------------------------------------------------------
function createPool( contract ISuperToken token, address admin, struct PoolConfig poolConfig) internal returns (contract ISuperfluidPool pool)
_Creates a new Superfluid Pool._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-48 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The Super Token address. |
| `admin` | address | The pool admin address. |
| `poolConfig` | struct PoolConfig | The pool configuration (see PoolConfig in IGeneralDistributionAgreementV1.sol) |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-25 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `pool` | contract ISuperfluidPool | The address of the deployed Superfluid Pool |
Fn createPool[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-createpool-1 "Direct link to Fn createPool")
------------------------------------------------------------------------------------------------------------------------------------------
function createPool( contract ISuperToken token, address admin) internal returns (contract ISuperfluidPool pool)
_Creates a new Superfluid Pool with default PoolConfig: units not transferrable, allow multi-distributors_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-49 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The Super Token address. |
| `admin` | address | The pool admin address. |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-26 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `pool` | contract ISuperfluidPool | The address of the deployed Superfluid Pool |
Fn createPool[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-createpool-2 "Direct link to Fn createPool")
------------------------------------------------------------------------------------------------------------------------------------------
function createPool( contract ISuperToken token) internal returns (contract ISuperfluidPool pool)
_Creates a new Superfluid Pool with default PoolConfig and the caller set as admin_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-50 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-27 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `pool` | contract ISuperfluidPool | The address of the deployed Superfluid Pool |
Fn claimAll[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-claimall "Direct link to Fn claimAll")
----------------------------------------------------------------------------------------------------------------------------------
function claimAll( contract ISuperToken token, contract ISuperfluidPool pool, address memberAddress) internal returns (bool)
_Claims all tokens from the pool._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-51 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The Super Token address. |
| `pool` | contract ISuperfluidPool | The Superfluid Pool to claim from. |
| `memberAddress` | address | The address of the member to claim for. |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-28 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | bool | A boolean value indicating whether the claim was successful. |
Fn claimAll (with User Data)[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-claimall-with-user-data "Direct link to Fn claimAll (with User Data)")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function claimAll( contract ISuperToken token, contract ISuperfluidPool pool, address memberAddress, bytes userData) internal returns (bool)
_Claims all tokens from the pool._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-52 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The Super Token address. |
| `pool` | contract ISuperfluidPool | The Superfluid Pool to claim from. |
| `memberAddress` | address | The address of the member to claim for. |
| `userData` | bytes | User-specific data. |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-29 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | bool | A boolean value indicating whether the claim was successful. |
Fn connectPool[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-connectpool "Direct link to Fn connectPool")
-------------------------------------------------------------------------------------------------------------------------------------------
function connectPool( contract ISuperToken token, contract ISuperfluidPool pool) internal returns (bool)
_Connects a pool member to `pool`._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-53 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The Super Token address. |
| `pool` | contract ISuperfluidPool | The Superfluid Pool to connect. |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-30 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | bool | A boolean value indicating whether the connection was successful. |
Fn connectPool (with User Data)[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-connectpool-with-user-data "Direct link to Fn connectPool (with User Data)")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function connectPool( contract ISuperToken token, contract ISuperfluidPool pool, bytes userData) internal returns (bool)
_Connects a pool member to `pool`._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-54 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The Super Token address. |
| `pool` | contract ISuperfluidPool | The Superfluid Pool to connect. |
| `userData` | bytes | User-specific data. |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-31 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | bool | A boolean value indicating whether the connection was successful. |
Fn disconnectPool[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-disconnectpool "Direct link to Fn disconnectPool")
----------------------------------------------------------------------------------------------------------------------------------------------------
function disconnectPool( contract ISuperToken token, contract ISuperfluidPool pool) internal returns (bool)
_Disconnects a pool member from `pool`._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-55 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The Super Token address. |
| `pool` | contract ISuperfluidPool | The Superfluid Pool to disconnect. |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-32 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | bool | A boolean value indicating whether the disconnection was successful. |
Fn disconnectPool (with User Data)[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-disconnectpool-with-user-data "Direct link to Fn disconnectPool (with User Data)")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function disconnectPool( contract ISuperToken token, contract ISuperfluidPool pool, bytes userData) internal returns (bool)
_Disconnects a pool member from `pool`._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-56 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The Super Token address. |
| `pool` | contract ISuperfluidPool | The Superfluid Pool to disconnect. |
| `userData` | bytes | User-specific data. |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-33 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | bool | A boolean value indicating whether the disconnection was successful. |
Fn distribute[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-distribute "Direct link to Fn distribute")
----------------------------------------------------------------------------------------------------------------------------------------
function distribute( contract ISuperToken token, contract ISuperfluidPool pool, uint256 requestedAmount) internal returns (bool)
_Tries to distribute `requestedAmount` amount of `token` from `from` to `pool`._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-57 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The Super Token address. |
| `pool` | contract ISuperfluidPool | The Superfluid Pool address. |
| `requestedAmount` | uint256 | The amount of tokens to distribute. |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-34 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | bool | A boolean value indicating whether the distribution was successful. |
Fn distribute (with User Data)[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-distribute-with-user-data "Direct link to Fn distribute (with User Data)")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function distribute( contract ISuperToken token, address from, contract ISuperfluidPool pool, uint256 requestedAmount, bytes userData) internal returns (bool)
_Tries to distribute `requestedAmount` amount of `token` from `from` to `pool`._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-58 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The Super Token address. |
| `from` | address | The address from which to distribute tokens. |
| `pool` | contract ISuperfluidPool | The Superfluid Pool address. |
| `requestedAmount` | uint256 | The amount of tokens to distribute. |
| `userData` | bytes | User-specific data. |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-35 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | bool | A boolean value indicating whether the distribution was successful. |
Fn distributeFlow[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-distributeflow "Direct link to Fn distributeFlow")
----------------------------------------------------------------------------------------------------------------------------------------------------
function distributeFlow( contract ISuperToken token, contract ISuperfluidPool pool, int96 requestedFlowRate) internal returns (bool)
_Tries to distribute flow at `requestedFlowRate` of `token` from `from` to `pool`._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-59 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The Super Token address. |
| `pool` | contract ISuperfluidPool | The Superfluid Pool address. |
| `requestedFlowRate` | int96 | The flow rate of tokens to distribute. |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-36 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | bool | A boolean value indicating whether the distribution was successful. |
Fn distributeFlow (with User Data)[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-distributeflow-with-user-data "Direct link to Fn distributeFlow (with User Data)")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function distributeFlow( contract ISuperToken token, address from, contract ISuperfluidPool pool, int96 requestedFlowRate, bytes userData) internal returns (bool)
_Tries to distribute flow at `requestedFlowRate` of `token` from `from` to `pool`._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-60 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The Super Token address. |
| `from` | address | The address from which to distribute tokens. |
| `pool` | contract ISuperfluidPool | The Superfluid Pool address. |
| `requestedFlowRate` | int96 | The flow rate of tokens to distribute. |
| `userData` | bytes | User-specific data. |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-37 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | bool | A boolean value indicating whether the distribution was successful. |
Fn claimAllWithCtx[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-claimallwithctx "Direct link to Fn claimAllWithCtx")
-------------------------------------------------------------------------------------------------------------------------------------------------------
function claimAllWithCtx( contract ISuperToken token, contract ISuperfluidPool pool, address memberAddress, bytes ctx) internal returns (bytes newCtx)
_Claims all tokens from the pool._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-61 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The Super Token address. |
| `pool` | contract ISuperfluidPool | The Superfluid Pool to claim from. |
| `memberAddress` | address | The address of the member to claim for. |
| `ctx` | bytes | Context bytes (see ISuperfluid.sol for Context struct) |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-38 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `newCtx` | bytes | The updated context after the execution of the agreement function |
Fn connectPoolWithCtx[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-connectpoolwithctx "Direct link to Fn connectPoolWithCtx")
----------------------------------------------------------------------------------------------------------------------------------------------------------------
function connectPoolWithCtx( contract ISuperToken token, contract ISuperfluidPool pool, bytes ctx) internal returns (bytes newCtx)
_Connects a pool member to `pool`._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-62 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The Super Token address. |
| `pool` | contract ISuperfluidPool | The Superfluid Pool to connect. |
| `ctx` | bytes | Context bytes (see ISuperfluid.sol for Context struct) |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-39 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `newCtx` | bytes | The updated context after the execution of the agreement function |
Fn disconnectPoolWithCtx[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-disconnectpoolwithctx "Direct link to Fn disconnectPoolWithCtx")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function disconnectPoolWithCtx( contract ISuperToken token, contract ISuperfluidPool pool, bytes ctx) internal returns (bytes newCtx)
_Disconnects a pool member from `pool`._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-63 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The Super Token address. |
| `pool` | contract ISuperfluidPool | The Superfluid Pool to disconnect. |
| `ctx` | bytes | Context bytes (see ISuperfluid.sol for Context struct) |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-40 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `newCtx` | bytes | The updated context after the execution of the agreement function |
Fn distributeWithCtx[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-distributewithctx "Direct link to Fn distributeWithCtx")
-------------------------------------------------------------------------------------------------------------------------------------------------------------
function distributeWithCtx( contract ISuperToken token, address from, contract ISuperfluidPool pool, uint256 requestedAmount, bytes ctx) internal returns (bytes newCtx)
_Tries to distribute `requestedAmount` amount of `token` from `from` to `pool`._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-64 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The Super Token address. |
| `from` | address | The address from which to distribute tokens. |
| `pool` | contract ISuperfluidPool | The Superfluid Pool address. |
| `requestedAmount` | uint256 | The amount of tokens to distribute. |
| `ctx` | bytes | Context bytes (see ISuperfluid.sol for Context struct) |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-41 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `newCtx` | bytes | The updated context after the execution of the agreement function |
Fn distributeFlowWithCtx[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-distributeflowwithctx "Direct link to Fn distributeFlowWithCtx")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function distributeFlowWithCtx( contract ISuperToken token, address from, contract ISuperfluidPool pool, int96 requestedFlowRate, bytes ctx) internal returns (bytes newCtx)
_Tries to distribute flow at `requestedFlowRate` of `token` from `from` to `pool`._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-65 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The Super Token address. |
| `from` | address | The address from which to distribute tokens. |
| `pool` | contract ISuperfluidPool | The Superfluid Pool address. |
| `requestedFlowRate` | int96 | The flow rate of tokens to distribute. |
| `ctx` | bytes | Context bytes (see ISuperfluid.sol for Context struct) |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-42 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `newCtx` | bytes | The updated context after the execution of the agreement function |
Fn getGDAFlowRate[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-getgdaflowrate "Direct link to Fn getGDAFlowRate")
----------------------------------------------------------------------------------------------------------------------------------------------------
function getGDAFlowRate( contract ISuperToken token, address distributor, contract ISuperfluidPool pool) internal returns (int96 flowRate)
_get flowrate between a distributor and pool for given token_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-66 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token used in flow |
| `distributor` | address | The ditributor of the flow |
| `pool` | contract ISuperfluidPool | The GDA pool |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-43 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `flowRate` | int96 | The flow rate |
Fn getFlowDistributionFlowRate[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-getflowdistributionflowrate "Direct link to Fn getFlowDistributionFlowRate")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function getFlowDistributionFlowRate( contract ISuperToken token, address from, contract ISuperfluidPool to) internal returns (int96)
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-67 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | |
| `from` | address | |
| `to` | contract ISuperfluidPool | |
alias of getGDAFlowRate
Fn getGDAFlowInfo[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-getgdaflowinfo "Direct link to Fn getGDAFlowInfo")
----------------------------------------------------------------------------------------------------------------------------------------------------
function getGDAFlowInfo( contract ISuperToken token, address distributor, contract ISuperfluidPool pool) internal returns (uint256 lastUpdated, int96 flowRate, uint256 deposit)
_get flow info of a distributor to a pool for given token_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-68 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | The token used in flow |
| `distributor` | address | The ditributor of the flow |
| `pool` | contract ISuperfluidPool | The GDA pool |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-44 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `lastUpdated` | uint256 | Timestamp of flow creation or last flowrate change |
| `flowRate` | int96 | The flow rate |
| `deposit` | uint256 | The amount of deposit the flow |
Fn getGDANetFlowRate[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-getgdanetflowrate "Direct link to Fn getGDANetFlowRate")
-------------------------------------------------------------------------------------------------------------------------------------------------------------
function getGDANetFlowRate( contract ISuperToken token, address account) internal returns (int96 flowRate)
_get GDA net flow rate for given account for given token_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-69 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | Super token address |
| `account` | address | Account to query |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-45 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `flowRate` | int96 | The net flow rate of the account |
Fn getGDANetFlowInfo[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-getgdanetflowinfo "Direct link to Fn getGDANetFlowInfo")
-------------------------------------------------------------------------------------------------------------------------------------------------------------
function getGDANetFlowInfo( contract ISuperToken token, address account) internal returns (uint256 lastUpdated, int96 flowRate, uint256 deposit, uint256 owedDeposit)
_get the aggregated GDA flow info of the account_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-70 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | Super token address |
| `account` | address | Account to query |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-46 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `lastUpdated` | uint256 | Timestamp of the last change of the net flow |
| `flowRate` | int96 | The net flow rate of token for account |
| `deposit` | uint256 | The sum of all deposits for account's flows |
| `owedDeposit` | uint256 | The sum of all owed deposits for account's flows |
Fn getPoolAdjustmentFlowRate[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-getpooladjustmentflowrate "Direct link to Fn getPoolAdjustmentFlowRate")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function getPoolAdjustmentFlowRate( contract ISuperToken token, contract ISuperfluidPool pool) internal returns (int96 poolAdjustmentFlowRate)
_get the adjustment flow rate for a pool_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-71 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | Super token address |
| `pool` | contract ISuperfluidPool | The pool to query |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-47 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `poolAdjustmentFlowRate` | int96 | The adjustment flow rate of the pool |
Fn getTotalAmountReceivedByMember[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-gettotalamountreceivedbymember "Direct link to Fn getTotalAmountReceivedByMember")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function getTotalAmountReceivedByMember( contract ISuperToken token, contract ISuperfluidPool pool, address memberAddr) internal returns (uint256 totalAmountReceived)
_Get the total amount of tokens received by a member via instant and flowing distributions_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-72 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | Super token address |
| `pool` | contract ISuperfluidPool | The pool to query |
| `memberAddr` | address | The member to query |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#return-values-48 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `totalAmountReceived` | uint256 | The total amount received by the member |
Fn getTotalAmountReceivedFromPool[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-gettotalamountreceivedfrompool "Direct link to Fn getTotalAmountReceivedFromPool")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function getTotalAmountReceivedFromPool( contract ISuperToken token, contract ISuperfluidPool pool, address memberAddr) internal returns (uint256 totalAmountReceived)
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-73 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | |
| `pool` | contract ISuperfluidPool | |
| `memberAddr` | address | |
alias for `getTotalAmountReceivedByMember`
Fn estimateFlowDistributionActualFlowRate[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-estimateflowdistributionactualflowrate "Direct link to Fn estimateFlowDistributionActualFlowRate")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function estimateFlowDistributionActualFlowRate( contract ISuperToken token, address from, contract ISuperfluidPool to, int96 requestedFlowRate) internal returns (int96 actualFlowRate, int96 totalDistributionFlowRate)
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-74 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | |
| `from` | address | |
| `to` | contract ISuperfluidPool | |
| `requestedFlowRate` | int96 | |
Fn estimateDistributionActualAmount[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-estimatedistributionactualamount "Direct link to Fn estimateDistributionActualAmount")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function estimateDistributionActualAmount( contract ISuperToken token, address from, contract ISuperfluidPool to, uint256 requestedAmount) internal returns (uint256 actualAmount)
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-75 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | |
| `from` | address | |
| `to` | contract ISuperfluidPool | |
| `requestedAmount` | uint256 | |
Fn isMemberConnected[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-ismemberconnected "Direct link to Fn isMemberConnected")
-------------------------------------------------------------------------------------------------------------------------------------------------------------
function isMemberConnected( contract ISuperToken token, address pool, address member) internal returns (bool)
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#parameters-76 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperToken | |
| `pool` | address | |
| `member` | address | |
* [Fn flowX](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-flowx)
* [Fn transferX](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-transferx)
* [Fn getFlowRate](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-getflowrate)
* [Fn getFlowInfo](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-getflowinfo)
* [Fn getNetFlowRate](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-getnetflowrate)
* [Fn getNetFlowInfo](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-getnetflowinfo)
* [Fn getBufferAmountByFlowRate](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-getbufferamountbyflowrate)
* [Fn flow](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-flow)
* [Fn flow (with User Data)](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-flow-with-user-data)
* [Fn createFlow](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-createflow)
* [Fn createFlow (with User Data)](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-createflow-with-user-data)
* [Fn updateFlow](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-updateflow)
* [Fn updateFlow (with User Data)](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-updateflow-with-user-data)
* [Fn deleteFlow](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-deleteflow)
* [Fn deleteFlow (with User Data)](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-deleteflow-with-user-data)
* [Fn flowFrom](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-flowfrom)
* [Fn flowFrom (with User Data)](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-flowfrom-with-user-data)
* [Fn setFlowPermissions](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-setflowpermissions)
* [Fn setMaxFlowPermissions](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-setmaxflowpermissions)
* [Fn revokeFlowPermissions](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-revokeflowpermissions)
* [Fn increaseFlowRateAllowance](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-increaseflowrateallowance)
* [Fn increaseFlowRateAllowance (with User Data)](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-increaseflowrateallowance-with-user-data)
* [Fn decreaseFlowRateAllowance](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-decreaseflowrateallowance)
* [Fn decreaseFlowRateAllowance (with User Data)](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-decreaseflowrateallowance-with-user-data)
* [Fn increaseFlowRateAllowanceWithPermissions](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-increaseflowrateallowancewithpermissions)
* [Fn increaseFlowRateAllowanceWithPermissions (with User Data)](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-increaseflowrateallowancewithpermissions-with-user-data)
* [Fn decreaseFlowRateAllowanceWithPermissions](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-decreaseflowrateallowancewithpermissions)
* [Fn decreaseFlowRateAllowanceWithPermissions (with User Data)](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-decreaseflowrateallowancewithpermissions-with-user-data)
* [Fn createFlowFrom](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-createflowfrom)
* [Fn createFlowFrom (with User Data)](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-createflowfrom-with-user-data)
* [Fn updateFlowFrom](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-updateflowfrom)
* [Fn updateFlowFrom (with User Data)](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-updateflowfrom-with-user-data)
* [Fn deleteFlowFrom](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-deleteflowfrom)
* [Fn deleteFlowFrom (with User Data)](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-deleteflowfrom-with-user-data)
* [Fn createFlowWithCtx](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-createflowwithctx)
* [Fn createFlowFromWithCtx](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-createflowfromwithctx)
* [Fn updateFlowWithCtx](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-updateflowwithctx)
* [Fn updateFlowFromWithCtx](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-updateflowfromwithctx)
* [Fn deleteFlowWithCtx](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-deleteflowwithctx)
* [Fn deleteFlowFromWithCtx](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-deleteflowfromwithctx)
* [Fn setFlowPermissionsWithCtx](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-setflowpermissionswithctx)
* [Fn setMaxFlowPermissionsWithCtx](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-setmaxflowpermissionswithctx)
* [Fn revokeFlowPermissionsWithCtx](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-revokeflowpermissionswithctx)
* [Fn getCFAFlowRate](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-getcfaflowrate)
* [Fn getCFAFlowInfo](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-getcfaflowinfo)
* [Fn getCFANetFlowRate](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-getcfanetflowrate)
* [Fn getCFANetFlowInfo](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-getcfanetflowinfo)
* [Fn getFlowPermissions](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-getflowpermissions)
* [Fn createPool](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-createpool)
* [Fn createPool](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-createpool-1)
* [Fn createPool](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-createpool-2)
* [Fn claimAll](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-claimall)
* [Fn claimAll (with User Data)](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-claimall-with-user-data)
* [Fn connectPool](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-connectpool)
* [Fn connectPool (with User Data)](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-connectpool-with-user-data)
* [Fn disconnectPool](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-disconnectpool)
* [Fn disconnectPool (with User Data)](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-disconnectpool-with-user-data)
* [Fn distribute](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-distribute)
* [Fn distribute (with User Data)](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-distribute-with-user-data)
* [Fn distributeFlow](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-distributeflow)
* [Fn distributeFlow (with User Data)](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-distributeflow-with-user-data)
* [Fn claimAllWithCtx](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-claimallwithctx)
* [Fn connectPoolWithCtx](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-connectpoolwithctx)
* [Fn disconnectPoolWithCtx](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-disconnectpoolwithctx)
* [Fn distributeWithCtx](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-distributewithctx)
* [Fn distributeFlowWithCtx](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-distributeflowwithctx)
* [Fn getGDAFlowRate](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-getgdaflowrate)
* [Fn getFlowDistributionFlowRate](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-getflowdistributionflowrate)
* [Fn getGDAFlowInfo](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-getgdaflowinfo)
* [Fn getGDANetFlowRate](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-getgdanetflowrate)
* [Fn getGDANetFlowInfo](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-getgdanetflowinfo)
* [Fn getPoolAdjustmentFlowRate](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-getpooladjustmentflowrate)
* [Fn getTotalAmountReceivedByMember](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-gettotalamountreceivedbymember)
* [Fn getTotalAmountReceivedFromPool](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-gettotalamountreceivedfrompool)
* [Fn estimateFlowDistributionActualFlowRate](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-estimateflowdistributionactualflowrate)
* [Fn estimateDistributionActualAmount](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-estimatedistributionactualamount)
* [Fn isMemberConnected](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library#fn-ismemberconnected)
---
# Subgraph Endpoints | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/technical-reference/subgraph#__docusaurus_skipToContent_fallback)
On this page
This document provides an overview of the available networks and their respective subgraph URLs. The format for the subgraph URL is the following: `https://subgraph-endpoints.superfluid.dev//protocol-v1`
Automations subgraphs
Automation subgraphs have the following formats:
* Vesting Scheduler: `https://subgraph-endpoints.superfluid.dev//vesting-scheduler`
* Flow Scheduler: `https://subgraph-endpoints.superfluid.dev//flow-scheduler`
* Auto-wrap: `https://subgraph-endpoints.superfluid.dev//auto-wrap`
Available Networks[](https://docs.superfluid.org/docs/technical-reference/subgraph#available-networks "Direct link to Available Networks")
--------------------------------------------------------------------------------------------------------------------------------------------
Below is a table of the available networks along with their details:
| Network Name | Canonical Name | Testnet | Chain ID | Subgraph URL |
| --- | --- | --- | --- | --- |
| Avalanche Fuji | avalanche-fuji | Yes | 43113 | [https://subgraph-endpoints.superfluid.dev/avalanche-fuji/protocol-v1](https://subgraph-endpoints.superfluid.dev/avalanche-fuji/protocol-v1) |
| Sepolia | eth-sepolia | Yes | 11155111 | [https://subgraph-endpoints.superfluid.dev/eth-sepolia/protocol-v1](https://subgraph-endpoints.superfluid.dev/eth-sepolia/protocol-v1) |
| Optimism Sepolia | optimism-sepolia | Yes | 11155420 | [https://subgraph-endpoints.superfluid.dev/optimism-sepolia/protocol-v1](https://subgraph-endpoints.superfluid.dev/optimism-sepolia/protocol-v1) |
| Scroll Sepolia | scroll-sepolia | Yes | 534351 | [https://subgraph-endpoints.superfluid.dev/scroll-sepolia/protocol-v1](https://subgraph-endpoints.superfluid.dev/scroll-sepolia/protocol-v1) |
| Gnosis Chain | xdai-mainnet | No | 100 | [https://subgraph-endpoints.superfluid.dev/xdai-mainnet/protocol-v1](https://subgraph-endpoints.superfluid.dev/xdai-mainnet/protocol-v1) |
| Polygon | polygon-mainnet | No | 137 | [https://subgraph-endpoints.superfluid.dev/polygon-mainnet/protocol-v1](https://subgraph-endpoints.superfluid.dev/polygon-mainnet/protocol-v1) |
| Optimism | optimism-mainnet | No | 10 | [https://subgraph-endpoints.superfluid.dev/optimism-mainnet/protocol-v1](https://subgraph-endpoints.superfluid.dev/optimism-mainnet/protocol-v1) |
| Arbitrum One | arbitrum-one | No | 42161 | [https://subgraph-endpoints.superfluid.dev/arbitrum-one/protocol-v1](https://subgraph-endpoints.superfluid.dev/arbitrum-one/protocol-v1) |
| Avalanche C | avalanche-c | No | 43114 | [https://subgraph-endpoints.superfluid.dev/avalanche-c/protocol-v1](https://subgraph-endpoints.superfluid.dev/avalanche-c/protocol-v1) |
| BNB Smart Chain | bsc-mainnet | No | 56 | [https://subgraph-endpoints.superfluid.dev/bsc-mainnet/protocol-v1](https://subgraph-endpoints.superfluid.dev/bsc-mainnet/protocol-v1) |
| Ethereum | eth-mainnet | No | 1 | [https://subgraph-endpoints.superfluid.dev/eth-mainnet/protocol-v1](https://subgraph-endpoints.superfluid.dev/eth-mainnet/protocol-v1) |
| Celo | celo-mainnet | No | 42220 | [https://subgraph-endpoints.superfluid.dev/celo-mainnet/protocol-v1](https://subgraph-endpoints.superfluid.dev/celo-mainnet/protocol-v1) |
| Base | base-mainnet | No | 8453 | [https://subgraph-endpoints.superfluid.dev/base-mainnet/protocol-v1](https://subgraph-endpoints.superfluid.dev/base-mainnet/protocol-v1) |
| Scroll | scroll-mainnet | No | 534352 | [https://subgraph-endpoints.superfluid.dev/scroll-mainnet/protocol-v1](https://subgraph-endpoints.superfluid.dev/scroll-mainnet/protocol-v1) |
| Degen Chain | degenchain | No | 666666666 | [https://subgraph-endpoints.superfluid.dev/degenchain/protocol-v1](https://subgraph-endpoints.superfluid.dev/degenchain/protocol-v1) |
* [Available Networks](https://docs.superfluid.org/docs/technical-reference/subgraph#available-networks)
---
# ISuperfluidPool | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#__docusaurus_skipToContent_fallback)
On this page
This is the technical reference related to the interface for any super token pool regardless of the distribution schemes.
ABI[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#abi "Direct link to ABI")
------------------------------------------------------------------------------------------------------
In order to interact with the `ISuperfluidPool` contract, you can use the following ABI:
Click here to show `ISuperfluidPool` ABI
[ { "inputs": [], "name": "SUPERFLUID_POOL_INVALID_TIME", "type": "error" }, { "inputs": [], "name": "SUPERFLUID_POOL_NOT_GDA", "type": "error" }, { "inputs": [], "name": "SUPERFLUID_POOL_NOT_POOL_ADMIN_OR_GDA", "type": "error" }, { "inputs": [], "name": "SUPERFLUID_POOL_NO_POOL_MEMBERS", "type": "error" }, { "inputs": [], "name": "SUPERFLUID_POOL_NO_ZERO_ADDRESS", "type": "error" }, { "inputs": [], "name": "SUPERFLUID_POOL_SELF_TRANSFER_NOT_ALLOWED", "type": "error" }, { "inputs": [], "name": "SUPERFLUID_POOL_TRANSFER_UNITS_NOT_ALLOWED", "type": "error" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "owner", "type": "address" }, { "indexed": true, "internalType": "address", "name": "spender", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "value", "type": "uint256" } ], "name": "Approval", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "contract ISuperfluidToken", "name": "token", "type": "address" }, { "indexed": true, "internalType": "address", "name": "member", "type": "address" }, { "indexed": false, "internalType": "int256", "name": "claimedAmount", "type": "int256" }, { "indexed": false, "internalType": "int256", "name": "totalClaimed", "type": "int256" } ], "name": "DistributionClaimed", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "contract ISuperfluidToken", "name": "token", "type": "address" }, { "indexed": true, "internalType": "address", "name": "member", "type": "address" }, { "indexed": false, "internalType": "uint128", "name": "oldUnits", "type": "uint128" }, { "indexed": false, "internalType": "uint128", "name": "newUnits", "type": "uint128" } ], "name": "MemberUnitsUpdated", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "from", "type": "address" }, { "indexed": true, "internalType": "address", "name": "to", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "value", "type": "uint256" } ], "name": "Transfer", "type": "event" }, { "inputs": [], "name": "admin", "outputs": [ { "internalType": "address", "name": "", "type": "address" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "owner", "type": "address" }, { "internalType": "address", "name": "spender", "type": "address" } ], "name": "allowance", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "uint256", "name": "value", "type": "uint256" } ], "name": "approve", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" } ], "name": "balanceOf", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "memberAddr", "type": "address" } ], "name": "claimAll", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "claimAll", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "uint256", "name": "subtractedValue", "type": "uint256" } ], "name": "decreaseAllowance", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "distributionFromAnyAddress", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "memberAddr", "type": "address" }, { "internalType": "uint32", "name": "time", "type": "uint32" } ], "name": "getClaimable", "outputs": [ { "internalType": "int256", "name": "", "type": "int256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "memberAddr", "type": "address" } ], "name": "getClaimableNow", "outputs": [ { "internalType": "int256", "name": "claimableBalance", "type": "int256" }, { "internalType": "uint256", "name": "timestamp", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "uint32", "name": "time", "type": "uint32" } ], "name": "getDisconnectedBalance", "outputs": [ { "internalType": "int256", "name": "balance", "type": "int256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "memberAddr", "type": "address" } ], "name": "getMemberFlowRate", "outputs": [ { "internalType": "int96", "name": "", "type": "int96" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "memberAddr", "type": "address" } ], "name": "getTotalAmountReceivedByMember", "outputs": [ { "internalType": "uint256", "name": "totalAmountReceived", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "getTotalConnectedFlowRate", "outputs": [ { "internalType": "int96", "name": "", "type": "int96" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "getTotalConnectedUnits", "outputs": [ { "internalType": "uint128", "name": "", "type": "uint128" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "getTotalDisconnectedFlowRate", "outputs": [ { "internalType": "int96", "name": "", "type": "int96" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "getTotalDisconnectedUnits", "outputs": [ { "internalType": "uint128", "name": "", "type": "uint128" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "getTotalFlowRate", "outputs": [ { "internalType": "int96", "name": "", "type": "int96" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "getTotalUnits", "outputs": [ { "internalType": "uint128", "name": "", "type": "uint128" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "memberAddr", "type": "address" } ], "name": "getUnits", "outputs": [ { "internalType": "uint128", "name": "", "type": "uint128" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "uint256", "name": "addedValue", "type": "uint256" } ], "name": "increaseAllowance", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "superToken", "outputs": [ { "internalType": "contract ISuperfluidToken", "name": "", "type": "address" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "totalSupply", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "to", "type": "address" }, { "internalType": "uint256", "name": "value", "type": "uint256" } ], "name": "transfer", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "from", "type": "address" }, { "internalType": "address", "name": "to", "type": "address" }, { "internalType": "uint256", "name": "value", "type": "uint256" } ], "name": "transferFrom", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "transferabilityForUnitsOwner", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "memberAddr", "type": "address" }, { "internalType": "uint128", "name": "newUnits", "type": "uint128" } ], "name": "updateMemberUnits", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" }]
SUPERFLUID\_POOL\_INVALID\_TIME[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#superfluid_pool_invalid_time "Direct link to SUPERFLUID_POOL_INVALID_TIME")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
error SUPERFLUID_POOL_INVALID_TIME()
SUPERFLUID\_POOL\_NO\_POOL\_MEMBERS[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#superfluid_pool_no_pool_members "Direct link to SUPERFLUID_POOL_NO_POOL_MEMBERS")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
error SUPERFLUID_POOL_NO_POOL_MEMBERS()
SUPERFLUID\_POOL\_NO\_ZERO\_ADDRESS[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#superfluid_pool_no_zero_address "Direct link to SUPERFLUID_POOL_NO_ZERO_ADDRESS")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
error SUPERFLUID_POOL_NO_ZERO_ADDRESS()
SUPERFLUID\_POOL\_NOT\_POOL\_ADMIN\_OR\_GDA[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#superfluid_pool_not_pool_admin_or_gda "Direct link to SUPERFLUID_POOL_NOT_POOL_ADMIN_OR_GDA")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
error SUPERFLUID_POOL_NOT_POOL_ADMIN_OR_GDA()
SUPERFLUID\_POOL\_NOT\_GDA[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#superfluid_pool_not_gda "Direct link to SUPERFLUID_POOL_NOT_GDA")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
error SUPERFLUID_POOL_NOT_GDA()
SUPERFLUID\_POOL\_TRANSFER\_UNITS\_NOT\_ALLOWED[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#superfluid_pool_transfer_units_not_allowed "Direct link to SUPERFLUID_POOL_TRANSFER_UNITS_NOT_ALLOWED")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
error SUPERFLUID_POOL_TRANSFER_UNITS_NOT_ALLOWED()
SUPERFLUID\_POOL\_SELF\_TRANSFER\_NOT\_ALLOWED[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#superfluid_pool_self_transfer_not_allowed "Direct link to SUPERFLUID_POOL_SELF_TRANSFER_NOT_ALLOWED")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
error SUPERFLUID_POOL_SELF_TRANSFER_NOT_ALLOWED()
Event MemberUnitsUpdated[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#event-memberunitsupdated "Direct link to Event MemberUnitsUpdated")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
event MemberUnitsUpdated( contract ISuperfluidToken token, address member, uint128 oldUnits, uint128 newUnits)
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#parameters "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperfluidToken | |
| `member` | address | |
| `oldUnits` | uint128 | |
| `newUnits` | uint128 | |
Event DistributionClaimed[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#event-distributionclaimed "Direct link to Event DistributionClaimed")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
event DistributionClaimed( contract ISuperfluidToken token, address member, int256 claimedAmount, int256 totalClaimed)
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#parameters-1 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `token` | contract ISuperfluidToken | |
| `member` | address | |
| `claimedAmount` | int256 | |
| `totalClaimed` | int256 | |
Fn transferabilityForUnitsOwner[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-transferabilityforunitsowner "Direct link to Fn transferabilityForUnitsOwner")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function transferabilityForUnitsOwner() external returns (bool)
A boolean indicating whether pool members can transfer their units
Fn distributionFromAnyAddress[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-distributionfromanyaddress "Direct link to Fn distributionFromAnyAddress")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function distributionFromAnyAddress() external returns (bool)
A boolean indicating whether addresses other than the pool admin can distribute via the pool
Fn admin[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-admin "Direct link to Fn admin")
---------------------------------------------------------------------------------------------------------------------
function admin() external returns (address)
_The admin is the creator of the pool and has permissions to update member units and is the recipient of the adjustment flow rate_
The pool admin
Fn superToken[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-supertoken "Direct link to Fn superToken")
------------------------------------------------------------------------------------------------------------------------------------
function superToken() external returns (contract ISuperfluidToken)
The SuperToken for the pool
Fn getTotalUnits[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-gettotalunits "Direct link to Fn getTotalUnits")
---------------------------------------------------------------------------------------------------------------------------------------------
function getTotalUnits() external returns (uint128)
The total units of the pool
Fn getTotalConnectedUnits[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-gettotalconnectedunits "Direct link to Fn getTotalConnectedUnits")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function getTotalConnectedUnits() external returns (uint128)
The total number of units of connected members
Fn getTotalDisconnectedUnits[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-gettotaldisconnectedunits "Direct link to Fn getTotalDisconnectedUnits")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function getTotalDisconnectedUnits() external returns (uint128)
The total number of units of disconnected members
Fn getUnits[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-getunits "Direct link to Fn getUnits")
------------------------------------------------------------------------------------------------------------------------------
function getUnits( address memberAddr) external returns (uint128)
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#parameters-2 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `memberAddr` | address | The address of the member |
The total number of units for `memberAddr`
Fn getTotalFlowRate[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-gettotalflowrate "Direct link to Fn getTotalFlowRate")
------------------------------------------------------------------------------------------------------------------------------------------------------
function getTotalFlowRate() external returns (int96)
The total flow rate of the pool
Fn getTotalConnectedFlowRate[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-gettotalconnectedflowrate "Direct link to Fn getTotalConnectedFlowRate")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function getTotalConnectedFlowRate() external returns (int96)
The flow rate of the connected members
Fn getTotalDisconnectedFlowRate[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-gettotaldisconnectedflowrate "Direct link to Fn getTotalDisconnectedFlowRate")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function getTotalDisconnectedFlowRate() external returns (int96)
The flow rate of the disconnected members
Fn getDisconnectedBalance[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-getdisconnectedbalance "Direct link to Fn getDisconnectedBalance")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function getDisconnectedBalance( uint32 time) external returns (int256 balance)
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#parameters-3 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `time` | uint32 | The time to query |
The balance of all the disconnected members at `time`
Fn getTotalAmountReceivedByMember[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-gettotalamountreceivedbymember "Direct link to Fn getTotalAmountReceivedByMember")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
function getTotalAmountReceivedByMember( address memberAddr) external returns (uint256 totalAmountReceived)
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#parameters-4 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `memberAddr` | address | The address of the member |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#return-values "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `totalAmountReceived` | uint256 | The total amount received by the member |
The total amount received by `memberAddr` in the pool
Fn getMemberFlowRate[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-getmemberflowrate "Direct link to Fn getMemberFlowRate")
---------------------------------------------------------------------------------------------------------------------------------------------------------
function getMemberFlowRate( address memberAddr) external returns (int96)
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#parameters-5 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `memberAddr` | address | The address of the member |
The flow rate a member is receiving from the pool
Fn getClaimable[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-getclaimable "Direct link to Fn getClaimable")
------------------------------------------------------------------------------------------------------------------------------------------
function getClaimable( address memberAddr, uint32 time) external returns (int256)
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#parameters-6 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `memberAddr` | address | The address of the member |
| `time` | uint32 | The time to query |
The claimable balance for `memberAddr` at `time` in the pool
Fn getClaimableNow[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-getclaimablenow "Direct link to Fn getClaimableNow")
---------------------------------------------------------------------------------------------------------------------------------------------------
function getClaimableNow( address memberAddr) external returns (int256 claimableBalance, uint256 timestamp)
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#parameters-7 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `memberAddr` | address | The address of the member |
The claimable balance for `memberAddr` at `block.timestamp` in the pool
Fn updateMemberUnits[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-updatememberunits "Direct link to Fn updateMemberUnits")
---------------------------------------------------------------------------------------------------------------------------------------------------------
function updateMemberUnits( address memberAddr, uint128 newUnits) external returns (bool)
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#parameters-8 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `memberAddr` | address | The address of the member |
| `newUnits` | uint128 | The new units for the member |
Sets `memberAddr` ownedUnits to `newUnits`
Fn claimAll[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-claimall "Direct link to Fn claimAll")
------------------------------------------------------------------------------------------------------------------------------
function claimAll( address memberAddr) external returns (bool)
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#parameters-9 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `memberAddr` | address | The address of the member |
Claims the claimable balance for `memberAddr` at `block.timestamp`
Fn claimAll[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-claimall-1 "Direct link to Fn claimAll")
--------------------------------------------------------------------------------------------------------------------------------
function claimAll() external returns (bool)
Claims the claimable balance for `msg.sender` at `block.timestamp`
Fn increaseAllowance[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-increaseallowance "Direct link to Fn increaseAllowance")
---------------------------------------------------------------------------------------------------------------------------------------------------------
function increaseAllowance( address spender, uint256 addedValue) external returns (bool)
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#parameters-10 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `spender` | address | The address of the spender |
| `addedValue` | uint256 | The amount to increase the allowance by |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#return-values-1 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | bool | true if successful |
Increases the allowance of `spender` by `addedValue`
Fn decreaseAllowance[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-decreaseallowance "Direct link to Fn decreaseAllowance")
---------------------------------------------------------------------------------------------------------------------------------------------------------
function decreaseAllowance( address spender, uint256 subtractedValue) external returns (bool)
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#parameters-11 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `spender` | address | The address of the spender |
| `subtractedValue` | uint256 | The amount to decrease the allowance by |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#return-values-2 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | bool | true if successful |
Decreases the allowance of `spender` by `subtractedValue`
* [ABI](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#abi)
* [SUPERFLUID\_POOL\_INVALID\_TIME](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#superfluid_pool_invalid_time)
* [SUPERFLUID\_POOL\_NO\_POOL\_MEMBERS](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#superfluid_pool_no_pool_members)
* [SUPERFLUID\_POOL\_NO\_ZERO\_ADDRESS](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#superfluid_pool_no_zero_address)
* [SUPERFLUID\_POOL\_NOT\_POOL\_ADMIN\_OR\_GDA](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#superfluid_pool_not_pool_admin_or_gda)
* [SUPERFLUID\_POOL\_NOT\_GDA](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#superfluid_pool_not_gda)
* [SUPERFLUID\_POOL\_TRANSFER\_UNITS\_NOT\_ALLOWED](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#superfluid_pool_transfer_units_not_allowed)
* [SUPERFLUID\_POOL\_SELF\_TRANSFER\_NOT\_ALLOWED](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#superfluid_pool_self_transfer_not_allowed)
* [Event MemberUnitsUpdated](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#event-memberunitsupdated)
* [Event DistributionClaimed](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#event-distributionclaimed)
* [Fn transferabilityForUnitsOwner](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-transferabilityforunitsowner)
* [Fn distributionFromAnyAddress](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-distributionfromanyaddress)
* [Fn admin](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-admin)
* [Fn superToken](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-supertoken)
* [Fn getTotalUnits](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-gettotalunits)
* [Fn getTotalConnectedUnits](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-gettotalconnectedunits)
* [Fn getTotalDisconnectedUnits](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-gettotaldisconnectedunits)
* [Fn getUnits](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-getunits)
* [Fn getTotalFlowRate](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-gettotalflowrate)
* [Fn getTotalConnectedFlowRate](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-gettotalconnectedflowrate)
* [Fn getTotalDisconnectedFlowRate](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-gettotaldisconnectedflowrate)
* [Fn getDisconnectedBalance](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-getdisconnectedbalance)
* [Fn getTotalAmountReceivedByMember](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-gettotalamountreceivedbymember)
* [Fn getMemberFlowRate](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-getmemberflowrate)
* [Fn getClaimable](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-getclaimable)
* [Fn getClaimableNow](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-getclaimablenow)
* [Fn updateMemberUnits](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-updatememberunits)
* [Fn claimAll](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-claimall)
* [Fn claimAll](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-claimall-1)
* [Fn increaseAllowance](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-increaseallowance)
* [Fn decreaseAllowance](https://docs.superfluid.org/docs/technical-reference/ISuperfluidPool#fn-decreaseallowance)
---
# Distribution Pools Explained | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/protocol/distributions/overview#__docusaurus_skipToContent_fallback)
On this page
Introduction[](https://docs.superfluid.org/docs/protocol/distributions/overview#introduction "Direct link to Introduction")
-----------------------------------------------------------------------------------------------------------------------------
Distributions is a Superfluid primitive that allows scalable are one-to-many or many-to-many transfer of value, in the form of discreet transfers or [Money Streaming](https://docs.superfluid.org/docs/protocol/money-streaming/overview)
. Superfluid's implementation of this concept allows for the creation of **Pools** with a designated **pool admin** who manages **units** for **pool members**. Members of these pools can receive funds either instantly or through continuous streaming, making this method highly efficient and scalable. We make the difference between two types of Distributions:
* **Instant Distribution**: They allow one discreet transfer of Super Tokens to any number of receivers with a fixed gas cost.
* **Streaming Distribution**: They allow for continuous distribution of funds to receivers through [Money Streaming](https://docs.superfluid.org/docs/protocol/money-streaming/overview)
to a Pool.
About Pools
Each distribution pool is denominated in a single Super Token but supports both Instant and Streaming Distributions.
* * *
* Instant Distribution
* Streaming Distribution
**Instant Distributions allow one transaction to distribute to any number of receivers with a fixed gas cost.**
_Click on the Blue Circle to initiate an Instant Distribution_
_By creating a Distribution Pool, you can distribute any token instantly_
**Instant Distributions allow for continuous distribution of funds to receivers through [Money Streaming](https://docs.superfluid.org/docs/protocol/money-streaming/overview)
to a Pool.**
_Watch how the continuous stream gets distributed automatically through the pool_
_By creating a Distribution Pool, you can distribute any stream with no gas cost_
* * *
### How It Works[](https://docs.superfluid.org/docs/protocol/distributions/overview#how-it-works "Direct link to How It Works")
1. **Create a Pool**: Deploying a pool contract creates a pool with a unique address.
2. **Assigning Proportions**: The pool admin sets proportions by allocating units to pool members.
3. **Distributing Tokens**: Pool members receive tokens based on their unit holdings.
info
Distributions are persistent, allowing multiple triggers with varying amounts. Units can be adjusted as needed.
Key Concepts[](https://docs.superfluid.org/docs/protocol/distributions/overview#key-concepts "Direct link to Key Concepts")
-----------------------------------------------------------------------------------------------------------------------------
* **Pool**: Channels for proportional token distribution.
* **Pool Admin**: Decides of the most important parameters of the distribution, including units.
* **Pool Members**: Receivers allocated units for distribution.
_Visualization of unit distribution in a pool_
Balancing Formula[](https://docs.superfluid.org/docs/protocol/distributions/overview#balancing-formula "Direct link to Balancing Formula")
--------------------------------------------------------------------------------------------------------------------------------------------
Calculates the current balance of an account subscribed to one or more distribution Indices.
-8cee6ee7099d99a46a705f89e61df22b.png)
info
Publishers can manage multiple Indices, and subscribers can be part of multiple Indices.
Pool Administration and Member Participation[](https://docs.superfluid.org/docs/protocol/distributions/overview#pool-administration-and-member-participation "Direct link to Pool Administration and Member Participation")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Pool admins manage units and distributions, while members receive distributions based on their units.
_Visualization of money streaming from an external source to a Pool and its members_
### Distribution Types[](https://docs.superfluid.org/docs/protocol/distributions/overview#distribution-types "Direct link to Distribution Types")
* **Instant Distribution**: One-time proportional token allocation.
* **Streaming Distribution**: Continuous flow of tokens over time.
### Major Design Choices[](https://docs.superfluid.org/docs/protocol/distributions/overview#major-design-choices "Direct link to Major Design Choices")
* **Pool Administration**: Admins have control over unit management and token distribution.
* **Member Participation**: Members receive distributions proportionate to their units.
* **ERC20 Compatibility**: The Pool interacts seamlessly with ERC20 standards.
Learn More about Distribution Pools[](https://docs.superfluid.org/docs/protocol/distributions/overview#learn-more-about-distribution-pools "Direct link to Learn More about Distribution Pools")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* [What is a Distribution Pool?](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#what-is-a-pool)
* [Important Pools related Functions](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#important-functions)
* [Example: Advertisement Auction DApp](https://docs.superfluid.org/docs/protocol/distributions/examples/example1)
* [Introduction](https://docs.superfluid.org/docs/protocol/distributions/overview#introduction)
* [How It Works](https://docs.superfluid.org/docs/protocol/distributions/overview#how-it-works)
* [Key Concepts](https://docs.superfluid.org/docs/protocol/distributions/overview#key-concepts)
* [Balancing Formula](https://docs.superfluid.org/docs/protocol/distributions/overview#balancing-formula)
* [Pool Administration and Member Participation](https://docs.superfluid.org/docs/protocol/distributions/overview#pool-administration-and-member-participation)
* [Distribution Types](https://docs.superfluid.org/docs/protocol/distributions/overview#distribution-types)
* [Major Design Choices](https://docs.superfluid.org/docs/protocol/distributions/overview#major-design-choices)
* [Learn More about Distribution Pools](https://docs.superfluid.org/docs/protocol/distributions/overview#learn-more-about-distribution-pools)
---
# ISETH | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/technical-reference/ISETH#__docusaurus_skipToContent_fallback)
On this page
ISETH is the interface for native Super Tokens.
ABI[](https://docs.superfluid.org/docs/technical-reference/ISETH#abi "Direct link to ABI")
--------------------------------------------------------------------------------------------
In order to interact with any contract satistying the `ISETH` interface, you can use the following ABI:
Click here to show `ISETH` ABI
[ { "inputs": [], "name": "SF_TOKEN_AGREEMENT_ALREADY_EXISTS", "type": "error" }, { "inputs": [], "name": "SF_TOKEN_AGREEMENT_DOES_NOT_EXIST", "type": "error" }, { "inputs": [], "name": "SF_TOKEN_BURN_INSUFFICIENT_BALANCE", "type": "error" }, { "inputs": [], "name": "SF_TOKEN_MOVE_INSUFFICIENT_BALANCE", "type": "error" }, { "inputs": [], "name": "SF_TOKEN_ONLY_HOST", "type": "error" }, { "inputs": [], "name": "SF_TOKEN_ONLY_LISTED_AGREEMENT", "type": "error" }, { "inputs": [], "name": "SUPER_TOKEN_APPROVE_FROM_ZERO_ADDRESS", "type": "error" }, { "inputs": [], "name": "SUPER_TOKEN_APPROVE_TO_ZERO_ADDRESS", "type": "error" }, { "inputs": [], "name": "SUPER_TOKEN_BURN_FROM_ZERO_ADDRESS", "type": "error" }, { "inputs": [], "name": "SUPER_TOKEN_CALLER_IS_NOT_OPERATOR_FOR_HOLDER", "type": "error" }, { "inputs": [], "name": "SUPER_TOKEN_INFLATIONARY_DEFLATIONARY_NOT_SUPPORTED", "type": "error" }, { "inputs": [], "name": "SUPER_TOKEN_MINT_TO_ZERO_ADDRESS", "type": "error" }, { "inputs": [], "name": "SUPER_TOKEN_NFT_PROXY_ADDRESS_CHANGED", "type": "error" }, { "inputs": [], "name": "SUPER_TOKEN_NOT_ERC777_TOKENS_RECIPIENT", "type": "error" }, { "inputs": [], "name": "SUPER_TOKEN_NO_UNDERLYING_TOKEN", "type": "error" }, { "inputs": [], "name": "SUPER_TOKEN_ONLY_ADMIN", "type": "error" }, { "inputs": [], "name": "SUPER_TOKEN_ONLY_GOV_OWNER", "type": "error" }, { "inputs": [], "name": "SUPER_TOKEN_ONLY_SELF", "type": "error" }, { "inputs": [], "name": "SUPER_TOKEN_TRANSFER_FROM_ZERO_ADDRESS", "type": "error" }, { "inputs": [], "name": "SUPER_TOKEN_TRANSFER_TO_ZERO_ADDRESS", "type": "error" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "oldAdmin", "type": "address" }, { "indexed": true, "internalType": "address", "name": "newAdmin", "type": "address" } ], "name": "AdminChanged", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "agreementClass", "type": "address" }, { "indexed": false, "internalType": "bytes32", "name": "id", "type": "bytes32" }, { "indexed": false, "internalType": "bytes32[]", "name": "data", "type": "bytes32[]" } ], "name": "AgreementCreated", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "agreementClass", "type": "address" }, { "indexed": false, "internalType": "bytes32", "name": "id", "type": "bytes32" }, { "indexed": true, "internalType": "address", "name": "penaltyAccount", "type": "address" }, { "indexed": true, "internalType": "address", "name": "rewardAccount", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "rewardAmount", "type": "uint256" } ], "name": "AgreementLiquidated", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": false, "internalType": "address", "name": "liquidatorAccount", "type": "address" }, { "indexed": true, "internalType": "address", "name": "agreementClass", "type": "address" }, { "indexed": false, "internalType": "bytes32", "name": "id", "type": "bytes32" }, { "indexed": true, "internalType": "address", "name": "penaltyAccount", "type": "address" }, { "indexed": true, "internalType": "address", "name": "bondAccount", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "rewardAmount", "type": "uint256" }, { "indexed": false, "internalType": "uint256", "name": "bailoutAmount", "type": "uint256" } ], "name": "AgreementLiquidatedBy", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "agreementClass", "type": "address" }, { "indexed": false, "internalType": "bytes32", "name": "id", "type": "bytes32" }, { "indexed": true, "internalType": "address", "name": "liquidatorAccount", "type": "address" }, { "indexed": true, "internalType": "address", "name": "targetAccount", "type": "address" }, { "indexed": false, "internalType": "address", "name": "rewardAmountReceiver", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "rewardAmount", "type": "uint256" }, { "indexed": false, "internalType": "int256", "name": "targetAccountBalanceDelta", "type": "int256" }, { "indexed": false, "internalType": "bytes", "name": "liquidationTypeData", "type": "bytes" } ], "name": "AgreementLiquidatedV2", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "agreementClass", "type": "address" }, { "indexed": true, "internalType": "address", "name": "account", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "slotId", "type": "uint256" } ], "name": "AgreementStateUpdated", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "agreementClass", "type": "address" }, { "indexed": false, "internalType": "bytes32", "name": "id", "type": "bytes32" } ], "name": "AgreementTerminated", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "agreementClass", "type": "address" }, { "indexed": false, "internalType": "bytes32", "name": "id", "type": "bytes32" }, { "indexed": false, "internalType": "bytes32[]", "name": "data", "type": "bytes32[]" } ], "name": "AgreementUpdated", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "owner", "type": "address" }, { "indexed": true, "internalType": "address", "name": "spender", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "value", "type": "uint256" } ], "name": "Approval", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "operator", "type": "address" }, { "indexed": true, "internalType": "address", "name": "tokenHolder", "type": "address" } ], "name": "AuthorizedOperator", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "bailoutAccount", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "bailoutAmount", "type": "uint256" } ], "name": "Bailout", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "operator", "type": "address" }, { "indexed": true, "internalType": "address", "name": "from", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" }, { "indexed": false, "internalType": "bytes", "name": "data", "type": "bytes" }, { "indexed": false, "internalType": "bytes", "name": "operatorData", "type": "bytes" } ], "name": "Burned", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "contract IConstantInflowNFT", "name": "constantInflowNFT", "type": "address" } ], "name": "ConstantInflowNFTCreated", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "contract IConstantOutflowNFT", "name": "constantOutflowNFT", "type": "address" } ], "name": "ConstantOutflowNFTCreated", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "operator", "type": "address" }, { "indexed": true, "internalType": "address", "name": "to", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" }, { "indexed": false, "internalType": "bytes", "name": "data", "type": "bytes" }, { "indexed": false, "internalType": "bytes", "name": "operatorData", "type": "bytes" } ], "name": "Minted", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "contract IPoolAdminNFT", "name": "poolAdminNFT", "type": "address" } ], "name": "PoolAdminNFTCreated", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "contract IPoolMemberNFT", "name": "poolMemberNFT", "type": "address" } ], "name": "PoolMemberNFTCreated", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "operator", "type": "address" }, { "indexed": true, "internalType": "address", "name": "tokenHolder", "type": "address" } ], "name": "RevokedOperator", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "operator", "type": "address" }, { "indexed": true, "internalType": "address", "name": "from", "type": "address" }, { "indexed": true, "internalType": "address", "name": "to", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" }, { "indexed": false, "internalType": "bytes", "name": "data", "type": "bytes" }, { "indexed": false, "internalType": "bytes", "name": "operatorData", "type": "bytes" } ], "name": "Sent", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "account", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "TokenDowngraded", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "account", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "TokenUpgraded", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "from", "type": "address" }, { "indexed": true, "internalType": "address", "name": "to", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "value", "type": "uint256" } ], "name": "Transfer", "type": "event" }, { "inputs": [], "name": "CONSTANT_INFLOW_NFT", "outputs": [ { "internalType": "contract IConstantInflowNFT", "name": "", "type": "address" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "CONSTANT_OUTFLOW_NFT", "outputs": [ { "internalType": "contract IConstantOutflowNFT", "name": "", "type": "address" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "POOL_ADMIN_NFT", "outputs": [ { "internalType": "contract IPoolAdminNFT", "name": "", "type": "address" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "POOL_MEMBER_NFT", "outputs": [ { "internalType": "contract IPoolMemberNFT", "name": "", "type": "address" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "owner", "type": "address" }, { "internalType": "address", "name": "spender", "type": "address" } ], "name": "allowance", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "approve", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "operator", "type": "address" } ], "name": "authorizeOperator", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" } ], "name": "balanceOf", "outputs": [ { "internalType": "uint256", "name": "balance", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "uint256", "name": "amount", "type": "uint256" }, { "internalType": "bytes", "name": "userData", "type": "bytes" } ], "name": "burn", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "newAdmin", "type": "address" } ], "name": "changeAdmin", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "bytes32", "name": "id", "type": "bytes32" }, { "internalType": "bytes32[]", "name": "data", "type": "bytes32[]" } ], "name": "createAgreement", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "decimals", "outputs": [ { "internalType": "uint8", "name": "", "type": "uint8" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "uint256", "name": "subtractedValue", "type": "uint256" } ], "name": "decreaseAllowance", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "defaultOperators", "outputs": [ { "internalType": "address[]", "name": "", "type": "address[]" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "downgrade", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "to", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "downgradeTo", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "uint256", "name": "wad", "type": "uint256" } ], "name": "downgradeToETH", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" } ], "name": "getAccountActiveAgreements", "outputs": [ { "internalType": "contract ISuperAgreement[]", "name": "activeAgreements", "type": "address[]" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "getAdmin", "outputs": [ { "internalType": "address", "name": "admin", "type": "address" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "agreementClass", "type": "address" }, { "internalType": "bytes32", "name": "id", "type": "bytes32" }, { "internalType": "uint256", "name": "dataLength", "type": "uint256" } ], "name": "getAgreementData", "outputs": [ { "internalType": "bytes32[]", "name": "data", "type": "bytes32[]" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "agreementClass", "type": "address" }, { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "uint256", "name": "slotId", "type": "uint256" }, { "internalType": "uint256", "name": "dataLength", "type": "uint256" } ], "name": "getAgreementStateSlot", "outputs": [ { "internalType": "bytes32[]", "name": "slotData", "type": "bytes32[]" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "getHost", "outputs": [ { "internalType": "address", "name": "host", "type": "address" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "getUnderlyingDecimals", "outputs": [ { "internalType": "uint8", "name": "underlyingDecimals", "type": "uint8" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "getUnderlyingToken", "outputs": [ { "internalType": "address", "name": "tokenAddr", "type": "address" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "granularity", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "uint256", "name": "addedValue", "type": "uint256" } ], "name": "increaseAllowance", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "contract IERC20", "name": "underlyingToken", "type": "address" }, { "internalType": "uint8", "name": "underlyingDecimals", "type": "uint8" }, { "internalType": "string", "name": "n", "type": "string" }, { "internalType": "string", "name": "s", "type": "string" } ], "name": "initialize", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "contract IERC20", "name": "underlyingToken", "type": "address" }, { "internalType": "uint8", "name": "underlyingDecimals", "type": "uint8" }, { "internalType": "string", "name": "n", "type": "string" }, { "internalType": "string", "name": "s", "type": "string" }, { "internalType": "address", "name": "admin", "type": "address" } ], "name": "initializeWithAdmin", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "uint256", "name": "timestamp", "type": "uint256" } ], "name": "isAccountCritical", "outputs": [ { "internalType": "bool", "name": "isCritical", "type": "bool" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" } ], "name": "isAccountCriticalNow", "outputs": [ { "internalType": "bool", "name": "isCritical", "type": "bool" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "uint256", "name": "timestamp", "type": "uint256" } ], "name": "isAccountSolvent", "outputs": [ { "internalType": "bool", "name": "isSolvent", "type": "bool" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" } ], "name": "isAccountSolventNow", "outputs": [ { "internalType": "bool", "name": "isSolvent", "type": "bool" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "operator", "type": "address" }, { "internalType": "address", "name": "tokenHolder", "type": "address" } ], "name": "isOperatorFor", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "bytes32", "name": "id", "type": "bytes32" }, { "internalType": "bytes", "name": "liquidationTypeData", "type": "bytes" }, { "internalType": "address", "name": "liquidatorAccount", "type": "address" }, { "internalType": "bool", "name": "useDefaultRewardAccount", "type": "bool" }, { "internalType": "address", "name": "targetAccount", "type": "address" }, { "internalType": "uint256", "name": "rewardAmount", "type": "uint256" }, { "internalType": "int256", "name": "targetAccountBalanceDelta", "type": "int256" } ], "name": "makeLiquidationPayoutsV2", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "name", "outputs": [ { "internalType": "string", "name": "", "type": "string" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "operationApprove", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "uint256", "name": "subtractedValue", "type": "uint256" } ], "name": "operationDecreaseAllowance", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "operationDowngrade", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "address", "name": "to", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "operationDowngradeTo", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "uint256", "name": "addedValue", "type": "uint256" } ], "name": "operationIncreaseAllowance", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "address", "name": "recipient", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" }, { "internalType": "bytes", "name": "userData", "type": "bytes" } ], "name": "operationSend", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "address", "name": "recipient", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "operationTransferFrom", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "operationUpgrade", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "address", "name": "to", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "operationUpgradeTo", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" }, { "internalType": "bytes", "name": "userData", "type": "bytes" }, { "internalType": "bytes", "name": "operatorData", "type": "bytes" } ], "name": "operatorBurn", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "sender", "type": "address" }, { "internalType": "address", "name": "recipient", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" }, { "internalType": "bytes", "name": "userData", "type": "bytes" }, { "internalType": "bytes", "name": "operatorData", "type": "bytes" } ], "name": "operatorSend", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "uint256", "name": "timestamp", "type": "uint256" } ], "name": "realtimeBalanceOf", "outputs": [ { "internalType": "int256", "name": "availableBalance", "type": "int256" }, { "internalType": "uint256", "name": "deposit", "type": "uint256" }, { "internalType": "uint256", "name": "owedDeposit", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" } ], "name": "realtimeBalanceOfNow", "outputs": [ { "internalType": "int256", "name": "availableBalance", "type": "int256" }, { "internalType": "uint256", "name": "deposit", "type": "uint256" }, { "internalType": "uint256", "name": "owedDeposit", "type": "uint256" }, { "internalType": "uint256", "name": "timestamp", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "operator", "type": "address" } ], "name": "revokeOperator", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "selfApproveFor", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" }, { "internalType": "bytes", "name": "userData", "type": "bytes" } ], "name": "selfBurn", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" }, { "internalType": "bytes", "name": "userData", "type": "bytes" } ], "name": "selfMint", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "sender", "type": "address" }, { "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "address", "name": "recipient", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "selfTransferFrom", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "recipient", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" }, { "internalType": "bytes", "name": "userData", "type": "bytes" } ], "name": "send", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "int256", "name": "delta", "type": "int256" } ], "name": "settleBalance", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "symbol", "outputs": [ { "internalType": "string", "name": "", "type": "string" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "bytes32", "name": "id", "type": "bytes32" }, { "internalType": "uint256", "name": "dataLength", "type": "uint256" } ], "name": "terminateAgreement", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "toUnderlyingAmount", "outputs": [ { "internalType": "uint256", "name": "underlyingAmount", "type": "uint256" }, { "internalType": "uint256", "name": "adjustedAmount", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "totalSupply", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "recipient", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "transfer", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "recipient", "type": "address" } ], "name": "transferAll", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "sender", "type": "address" }, { "internalType": "address", "name": "recipient", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "transferFrom", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "bytes32", "name": "id", "type": "bytes32" }, { "internalType": "bytes32[]", "name": "data", "type": "bytes32[]" } ], "name": "updateAgreementData", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "uint256", "name": "slotId", "type": "uint256" }, { "internalType": "bytes32[]", "name": "slotData", "type": "bytes32[]" } ], "name": "updateAgreementStateSlot", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "upgrade", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "upgradeByETH", "outputs": [], "stateMutability": "payable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "to", "type": "address" } ], "name": "upgradeByETHTo", "outputs": [], "stateMutability": "payable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "to", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" }, { "internalType": "bytes", "name": "userData", "type": "bytes" } ], "name": "upgradeTo", "outputs": [], "stateMutability": "nonpayable", "type": "function" }]
Fn upgradeByETH[](https://docs.superfluid.org/docs/technical-reference/ISETH#fn-upgradebyeth "Direct link to Fn upgradeByETH")
--------------------------------------------------------------------------------------------------------------------------------
function upgradeByETH() external
Fn upgradeByETHTo[](https://docs.superfluid.org/docs/technical-reference/ISETH#fn-upgradebyethto "Direct link to Fn upgradeByETHTo")
--------------------------------------------------------------------------------------------------------------------------------------
function upgradeByETHTo( address to) external
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISETH#parameters "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `to` | address | |
Fn downgradeToETH[](https://docs.superfluid.org/docs/technical-reference/ISETH#fn-downgradetoeth "Direct link to Fn downgradeToETH")
--------------------------------------------------------------------------------------------------------------------------------------
function downgradeToETH( uint256 wad) external
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISETH#parameters-1 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `wad` | uint256 | |
ISETH
=====
**Super ETH (SETH) full interface**
* [ABI](https://docs.superfluid.org/docs/technical-reference/ISETH#abi)
* [Fn upgradeByETH](https://docs.superfluid.org/docs/technical-reference/ISETH#fn-upgradebyeth)
* [Fn upgradeByETHTo](https://docs.superfluid.org/docs/technical-reference/ISETH#fn-upgradebyethto)
* [Fn downgradeToETH](https://docs.superfluid.org/docs/technical-reference/ISETH#fn-downgradetoeth)
---
# ISuperToken | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/technical-reference/ISuperToken#__docusaurus_skipToContent_fallback)
On this page
This is the technical reference related to the interface for Super Tokens.
Implementation addresses[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#implementation-addresses "Direct link to Implementation addresses")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
Super Token deployments work in a proxy pattern with the original implementation being comon between all super tokens for each chain. The implementation address for the SuperToken is different for each network and can be found in the SuperTokenFactory at the method `getSuperTokenLogic`.
To get the addresses of all the SuperTokenFactory contracts, you can use the [Superfluid Explorer](https://explorer.superfluid.finance/)
, section Protocol.
ABI[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#abi "Direct link to ABI")
--------------------------------------------------------------------------------------------------
In order to interact with any contract satistying the `ISuperToken` interface, you can use the following ABI:
Click here to show `ISuperToken` ABI
[ { "inputs": [], "name": "SF_TOKEN_AGREEMENT_ALREADY_EXISTS", "type": "error" }, { "inputs": [], "name": "SF_TOKEN_AGREEMENT_DOES_NOT_EXIST", "type": "error" }, { "inputs": [], "name": "SF_TOKEN_BURN_INSUFFICIENT_BALANCE", "type": "error" }, { "inputs": [], "name": "SF_TOKEN_MOVE_INSUFFICIENT_BALANCE", "type": "error" }, { "inputs": [], "name": "SF_TOKEN_ONLY_HOST", "type": "error" }, { "inputs": [], "name": "SF_TOKEN_ONLY_LISTED_AGREEMENT", "type": "error" }, { "inputs": [], "name": "SUPER_TOKEN_APPROVE_FROM_ZERO_ADDRESS", "type": "error" }, { "inputs": [], "name": "SUPER_TOKEN_APPROVE_TO_ZERO_ADDRESS", "type": "error" }, { "inputs": [], "name": "SUPER_TOKEN_BURN_FROM_ZERO_ADDRESS", "type": "error" }, { "inputs": [], "name": "SUPER_TOKEN_CALLER_IS_NOT_OPERATOR_FOR_HOLDER", "type": "error" }, { "inputs": [], "name": "SUPER_TOKEN_INFLATIONARY_DEFLATIONARY_NOT_SUPPORTED", "type": "error" }, { "inputs": [], "name": "SUPER_TOKEN_MINT_TO_ZERO_ADDRESS", "type": "error" }, { "inputs": [], "name": "SUPER_TOKEN_NFT_PROXY_ADDRESS_CHANGED", "type": "error" }, { "inputs": [], "name": "SUPER_TOKEN_NOT_ERC777_TOKENS_RECIPIENT", "type": "error" }, { "inputs": [], "name": "SUPER_TOKEN_NO_UNDERLYING_TOKEN", "type": "error" }, { "inputs": [], "name": "SUPER_TOKEN_ONLY_ADMIN", "type": "error" }, { "inputs": [], "name": "SUPER_TOKEN_ONLY_GOV_OWNER", "type": "error" }, { "inputs": [], "name": "SUPER_TOKEN_ONLY_SELF", "type": "error" }, { "inputs": [], "name": "SUPER_TOKEN_TRANSFER_FROM_ZERO_ADDRESS", "type": "error" }, { "inputs": [], "name": "SUPER_TOKEN_TRANSFER_TO_ZERO_ADDRESS", "type": "error" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "oldAdmin", "type": "address" }, { "indexed": true, "internalType": "address", "name": "newAdmin", "type": "address" } ], "name": "AdminChanged", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "agreementClass", "type": "address" }, { "indexed": false, "internalType": "bytes32", "name": "id", "type": "bytes32" }, { "indexed": false, "internalType": "bytes32[]", "name": "data", "type": "bytes32[]" } ], "name": "AgreementCreated", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "agreementClass", "type": "address" }, { "indexed": false, "internalType": "bytes32", "name": "id", "type": "bytes32" }, { "indexed": true, "internalType": "address", "name": "penaltyAccount", "type": "address" }, { "indexed": true, "internalType": "address", "name": "rewardAccount", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "rewardAmount", "type": "uint256" } ], "name": "AgreementLiquidated", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": false, "internalType": "address", "name": "liquidatorAccount", "type": "address" }, { "indexed": true, "internalType": "address", "name": "agreementClass", "type": "address" }, { "indexed": false, "internalType": "bytes32", "name": "id", "type": "bytes32" }, { "indexed": true, "internalType": "address", "name": "penaltyAccount", "type": "address" }, { "indexed": true, "internalType": "address", "name": "bondAccount", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "rewardAmount", "type": "uint256" }, { "indexed": false, "internalType": "uint256", "name": "bailoutAmount", "type": "uint256" } ], "name": "AgreementLiquidatedBy", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "agreementClass", "type": "address" }, { "indexed": false, "internalType": "bytes32", "name": "id", "type": "bytes32" }, { "indexed": true, "internalType": "address", "name": "liquidatorAccount", "type": "address" }, { "indexed": true, "internalType": "address", "name": "targetAccount", "type": "address" }, { "indexed": false, "internalType": "address", "name": "rewardAmountReceiver", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "rewardAmount", "type": "uint256" }, { "indexed": false, "internalType": "int256", "name": "targetAccountBalanceDelta", "type": "int256" }, { "indexed": false, "internalType": "bytes", "name": "liquidationTypeData", "type": "bytes" } ], "name": "AgreementLiquidatedV2", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "agreementClass", "type": "address" }, { "indexed": true, "internalType": "address", "name": "account", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "slotId", "type": "uint256" } ], "name": "AgreementStateUpdated", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "agreementClass", "type": "address" }, { "indexed": false, "internalType": "bytes32", "name": "id", "type": "bytes32" } ], "name": "AgreementTerminated", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "agreementClass", "type": "address" }, { "indexed": false, "internalType": "bytes32", "name": "id", "type": "bytes32" }, { "indexed": false, "internalType": "bytes32[]", "name": "data", "type": "bytes32[]" } ], "name": "AgreementUpdated", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "owner", "type": "address" }, { "indexed": true, "internalType": "address", "name": "spender", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "value", "type": "uint256" } ], "name": "Approval", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "operator", "type": "address" }, { "indexed": true, "internalType": "address", "name": "tokenHolder", "type": "address" } ], "name": "AuthorizedOperator", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "bailoutAccount", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "bailoutAmount", "type": "uint256" } ], "name": "Bailout", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "operator", "type": "address" }, { "indexed": true, "internalType": "address", "name": "from", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" }, { "indexed": false, "internalType": "bytes", "name": "data", "type": "bytes" }, { "indexed": false, "internalType": "bytes", "name": "operatorData", "type": "bytes" } ], "name": "Burned", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "contract IConstantInflowNFT", "name": "constantInflowNFT", "type": "address" } ], "name": "ConstantInflowNFTCreated", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "contract IConstantOutflowNFT", "name": "constantOutflowNFT", "type": "address" } ], "name": "ConstantOutflowNFTCreated", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "operator", "type": "address" }, { "indexed": true, "internalType": "address", "name": "to", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" }, { "indexed": false, "internalType": "bytes", "name": "data", "type": "bytes" }, { "indexed": false, "internalType": "bytes", "name": "operatorData", "type": "bytes" } ], "name": "Minted", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "contract IPoolAdminNFT", "name": "poolAdminNFT", "type": "address" } ], "name": "PoolAdminNFTCreated", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "contract IPoolMemberNFT", "name": "poolMemberNFT", "type": "address" } ], "name": "PoolMemberNFTCreated", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "operator", "type": "address" }, { "indexed": true, "internalType": "address", "name": "tokenHolder", "type": "address" } ], "name": "RevokedOperator", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "operator", "type": "address" }, { "indexed": true, "internalType": "address", "name": "from", "type": "address" }, { "indexed": true, "internalType": "address", "name": "to", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" }, { "indexed": false, "internalType": "bytes", "name": "data", "type": "bytes" }, { "indexed": false, "internalType": "bytes", "name": "operatorData", "type": "bytes" } ], "name": "Sent", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "account", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "TokenDowngraded", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "account", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "TokenUpgraded", "type": "event" }, { "anonymous": false, "inputs": [ { "indexed": true, "internalType": "address", "name": "from", "type": "address" }, { "indexed": true, "internalType": "address", "name": "to", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "value", "type": "uint256" } ], "name": "Transfer", "type": "event" }, { "inputs": [], "name": "CONSTANT_INFLOW_NFT", "outputs": [ { "internalType": "contract IConstantInflowNFT", "name": "", "type": "address" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "CONSTANT_OUTFLOW_NFT", "outputs": [ { "internalType": "contract IConstantOutflowNFT", "name": "", "type": "address" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "POOL_ADMIN_NFT", "outputs": [ { "internalType": "contract IPoolAdminNFT", "name": "", "type": "address" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "POOL_MEMBER_NFT", "outputs": [ { "internalType": "contract IPoolMemberNFT", "name": "", "type": "address" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "owner", "type": "address" }, { "internalType": "address", "name": "spender", "type": "address" } ], "name": "allowance", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "approve", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "operator", "type": "address" } ], "name": "authorizeOperator", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" } ], "name": "balanceOf", "outputs": [ { "internalType": "uint256", "name": "balance", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "uint256", "name": "amount", "type": "uint256" }, { "internalType": "bytes", "name": "userData", "type": "bytes" } ], "name": "burn", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "newAdmin", "type": "address" } ], "name": "changeAdmin", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "bytes32", "name": "id", "type": "bytes32" }, { "internalType": "bytes32[]", "name": "data", "type": "bytes32[]" } ], "name": "createAgreement", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "decimals", "outputs": [ { "internalType": "uint8", "name": "", "type": "uint8" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "uint256", "name": "subtractedValue", "type": "uint256" } ], "name": "decreaseAllowance", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "defaultOperators", "outputs": [ { "internalType": "address[]", "name": "", "type": "address[]" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "downgrade", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "to", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "downgradeTo", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" } ], "name": "getAccountActiveAgreements", "outputs": [ { "internalType": "contract ISuperAgreement[]", "name": "activeAgreements", "type": "address[]" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "getAdmin", "outputs": [ { "internalType": "address", "name": "admin", "type": "address" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "agreementClass", "type": "address" }, { "internalType": "bytes32", "name": "id", "type": "bytes32" }, { "internalType": "uint256", "name": "dataLength", "type": "uint256" } ], "name": "getAgreementData", "outputs": [ { "internalType": "bytes32[]", "name": "data", "type": "bytes32[]" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "agreementClass", "type": "address" }, { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "uint256", "name": "slotId", "type": "uint256" }, { "internalType": "uint256", "name": "dataLength", "type": "uint256" } ], "name": "getAgreementStateSlot", "outputs": [ { "internalType": "bytes32[]", "name": "slotData", "type": "bytes32[]" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "getHost", "outputs": [ { "internalType": "address", "name": "host", "type": "address" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "getUnderlyingDecimals", "outputs": [ { "internalType": "uint8", "name": "underlyingDecimals", "type": "uint8" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "getUnderlyingToken", "outputs": [ { "internalType": "address", "name": "tokenAddr", "type": "address" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "granularity", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "uint256", "name": "addedValue", "type": "uint256" } ], "name": "increaseAllowance", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "contract IERC20", "name": "underlyingToken", "type": "address" }, { "internalType": "uint8", "name": "underlyingDecimals", "type": "uint8" }, { "internalType": "string", "name": "n", "type": "string" }, { "internalType": "string", "name": "s", "type": "string" } ], "name": "initialize", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "contract IERC20", "name": "underlyingToken", "type": "address" }, { "internalType": "uint8", "name": "underlyingDecimals", "type": "uint8" }, { "internalType": "string", "name": "n", "type": "string" }, { "internalType": "string", "name": "s", "type": "string" }, { "internalType": "address", "name": "admin", "type": "address" } ], "name": "initializeWithAdmin", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "uint256", "name": "timestamp", "type": "uint256" } ], "name": "isAccountCritical", "outputs": [ { "internalType": "bool", "name": "isCritical", "type": "bool" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" } ], "name": "isAccountCriticalNow", "outputs": [ { "internalType": "bool", "name": "isCritical", "type": "bool" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "uint256", "name": "timestamp", "type": "uint256" } ], "name": "isAccountSolvent", "outputs": [ { "internalType": "bool", "name": "isSolvent", "type": "bool" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" } ], "name": "isAccountSolventNow", "outputs": [ { "internalType": "bool", "name": "isSolvent", "type": "bool" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "operator", "type": "address" }, { "internalType": "address", "name": "tokenHolder", "type": "address" } ], "name": "isOperatorFor", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "bytes32", "name": "id", "type": "bytes32" }, { "internalType": "bytes", "name": "liquidationTypeData", "type": "bytes" }, { "internalType": "address", "name": "liquidatorAccount", "type": "address" }, { "internalType": "bool", "name": "useDefaultRewardAccount", "type": "bool" }, { "internalType": "address", "name": "targetAccount", "type": "address" }, { "internalType": "uint256", "name": "rewardAmount", "type": "uint256" }, { "internalType": "int256", "name": "targetAccountBalanceDelta", "type": "int256" } ], "name": "makeLiquidationPayoutsV2", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "name", "outputs": [ { "internalType": "string", "name": "", "type": "string" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "operationApprove", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "uint256", "name": "subtractedValue", "type": "uint256" } ], "name": "operationDecreaseAllowance", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "operationDowngrade", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "address", "name": "to", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "operationDowngradeTo", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "uint256", "name": "addedValue", "type": "uint256" } ], "name": "operationIncreaseAllowance", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "address", "name": "recipient", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" }, { "internalType": "bytes", "name": "userData", "type": "bytes" } ], "name": "operationSend", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "address", "name": "recipient", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "operationTransferFrom", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "operationUpgrade", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "address", "name": "to", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "operationUpgradeTo", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" }, { "internalType": "bytes", "name": "userData", "type": "bytes" }, { "internalType": "bytes", "name": "operatorData", "type": "bytes" } ], "name": "operatorBurn", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "sender", "type": "address" }, { "internalType": "address", "name": "recipient", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" }, { "internalType": "bytes", "name": "userData", "type": "bytes" }, { "internalType": "bytes", "name": "operatorData", "type": "bytes" } ], "name": "operatorSend", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "uint256", "name": "timestamp", "type": "uint256" } ], "name": "realtimeBalanceOf", "outputs": [ { "internalType": "int256", "name": "availableBalance", "type": "int256" }, { "internalType": "uint256", "name": "deposit", "type": "uint256" }, { "internalType": "uint256", "name": "owedDeposit", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" } ], "name": "realtimeBalanceOfNow", "outputs": [ { "internalType": "int256", "name": "availableBalance", "type": "int256" }, { "internalType": "uint256", "name": "deposit", "type": "uint256" }, { "internalType": "uint256", "name": "owedDeposit", "type": "uint256" }, { "internalType": "uint256", "name": "timestamp", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "operator", "type": "address" } ], "name": "revokeOperator", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "selfApproveFor", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" }, { "internalType": "bytes", "name": "userData", "type": "bytes" } ], "name": "selfBurn", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" }, { "internalType": "bytes", "name": "userData", "type": "bytes" } ], "name": "selfMint", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "sender", "type": "address" }, { "internalType": "address", "name": "spender", "type": "address" }, { "internalType": "address", "name": "recipient", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "selfTransferFrom", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "recipient", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" }, { "internalType": "bytes", "name": "userData", "type": "bytes" } ], "name": "send", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "int256", "name": "delta", "type": "int256" } ], "name": "settleBalance", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "symbol", "outputs": [ { "internalType": "string", "name": "", "type": "string" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "bytes32", "name": "id", "type": "bytes32" }, { "internalType": "uint256", "name": "dataLength", "type": "uint256" } ], "name": "terminateAgreement", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "toUnderlyingAmount", "outputs": [ { "internalType": "uint256", "name": "underlyingAmount", "type": "uint256" }, { "internalType": "uint256", "name": "adjustedAmount", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "totalSupply", "outputs": [ { "internalType": "uint256", "name": "", "type": "uint256" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "recipient", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "transfer", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "recipient", "type": "address" } ], "name": "transferAll", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "sender", "type": "address" }, { "internalType": "address", "name": "recipient", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "transferFrom", "outputs": [ { "internalType": "bool", "name": "", "type": "bool" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "bytes32", "name": "id", "type": "bytes32" }, { "internalType": "bytes32[]", "name": "data", "type": "bytes32[]" } ], "name": "updateAgreementData", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "account", "type": "address" }, { "internalType": "uint256", "name": "slotId", "type": "uint256" }, { "internalType": "bytes32[]", "name": "slotData", "type": "bytes32[]" } ], "name": "updateAgreementStateSlot", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "uint256", "name": "amount", "type": "uint256" } ], "name": "upgrade", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "address", "name": "to", "type": "address" }, { "internalType": "uint256", "name": "amount", "type": "uint256" }, { "internalType": "bytes", "name": "userData", "type": "bytes" } ], "name": "upgradeTo", "outputs": [], "stateMutability": "nonpayable", "type": "function" }]
Functions[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#functions "Direct link to Functions")
--------------------------------------------------------------------------------------------------------------------
### Fn initialize[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-initialize "Direct link to Fn initialize")
function initialize( contract IERC20 underlyingToken, uint8 underlyingDecimals, string n, string s) external
_Initialize the contract_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `underlyingToken` | contract IERC20 | |
| `underlyingDecimals` | uint8 | |
| `n` | string | |
| `s` | string | |
### Fn initializeWithAdmin[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-initializewithadmin "Direct link to Fn initializeWithAdmin")
function initializeWithAdmin( contract IERC20 underlyingToken, uint8 underlyingDecimals, string n, string s, address admin) external
_Initialize the contract with an admin_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-1 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `underlyingToken` | contract IERC20 | |
| `underlyingDecimals` | uint8 | |
| `n` | string | |
| `s` | string | |
| `admin` | address | |
### Fn changeAdmin[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-changeadmin "Direct link to Fn changeAdmin")
function changeAdmin( address newAdmin) external
_Only the current admin can call this function if admin is address(0), it is implicitly the host address_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-2 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `newAdmin` | address | New admin address |
Changes the admin for the SuperToken
### Fn getAdmin[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-getadmin "Direct link to Fn getAdmin")
function getAdmin() external returns (address admin)
_Returns the admin address for the SuperToken_
### Fn CONSTANT\_OUTFLOW\_NFT[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-constant_outflow_nft "Direct link to Fn CONSTANT_OUTFLOW_NFT")
function CONSTANT_OUTFLOW_NFT() external returns (contract IConstantOutflowNFT)
### Fn CONSTANT\_INFLOW\_NFT[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-constant_inflow_nft "Direct link to Fn CONSTANT_INFLOW_NFT")
function CONSTANT_INFLOW_NFT() external returns (contract IConstantInflowNFT)
### Fn POOL\_ADMIN\_NFT[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-pool_admin_nft "Direct link to Fn POOL_ADMIN_NFT")
function POOL_ADMIN_NFT() external returns (contract IPoolAdminNFT)
### Fn POOL\_MEMBER\_NFT[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-pool_member_nft "Direct link to Fn POOL_MEMBER_NFT")
function POOL_MEMBER_NFT() external returns (contract IPoolMemberNFT)
### Fn name[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-name "Direct link to Fn name")
function name() external returns (string)
_Returns the name of the token._
### Fn symbol[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-symbol "Direct link to Fn symbol")
function symbol() external returns (string)
_Returns the symbol of the token, usually a shorter version of the name._
### Fn decimals[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-decimals "Direct link to Fn decimals")
function decimals() external returns (uint8)
\_Returns the number of decimals used to get its user representation. For example, if `decimals` equals `2`, a balance of `505` tokens should be displayed to a user as `5,05` (`505 / 10 ** 2`).
Tokens usually opt for a value of 18, imitating the relationship between Ether and Wei. This is the value ERC20 uses, unless _setupDecimals is called._
#### Note[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#note "Direct link to Note")
SuperToken always uses 18 decimals.
This information is only used for _display_ purposes: it in no way affects any of the arithmetic of the contract, including [IERC20-balanceOf](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20)
and [IERC20-transfer](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20)
.
### Fn totalSupply[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-totalsupply "Direct link to Fn totalSupply")
function totalSupply() external returns (uint256)
_See [IERC20-totalSupply](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20)
._
### Fn balanceOf[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-balanceof "Direct link to Fn balanceOf")
function balanceOf( address account) external returns (uint256 balance)
_Returns the amount of tokens owned by an account (`owner`)._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-3 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `account` | address | |
### Fn transfer[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-transfer "Direct link to Fn transfer")
function transfer( address recipient, uint256 amount) external returns (bool)
_Moves `amount` tokens from the caller's account to `recipient`._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-4 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `recipient` | address | |
| `amount` | uint256 | |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#return-values "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | bool | Returns Success a boolean value indicating whether the operation succeeded. |
#### Emits[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#emits "Direct link to Emits")
a ERC20 Transfer event.
### Fn allowance[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-allowance "Direct link to Fn allowance")
function allowance( address owner, address spender) external returns (uint256)
_Returns the remaining number of tokens that `spender` will be allowed to spend on behalf of `owner` through [transferFrom](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20)
. This is zero by default._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-5 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `owner` | address | |
| `spender` | address | |
This value changes when [approve](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20)
or [transferFrom](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20)
are called.
### Fn approve[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-approve "Direct link to Fn approve")
function approve( address spender, uint256 amount) external returns (bool)
_Sets `amount` as the allowance of `spender` over the caller's tokens._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-6 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `spender` | address | |
| `amount` | uint256 | |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#return-values-1 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | bool | Returns Success a boolean value indicating whether the operation succeeded. |
#### Note[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#note-1 "Direct link to Note")
Beware that changing an allowance with this method brings the risk that someone may use both the old and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards: [https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729](https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729)
#### Emits[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#emits-1 "Direct link to Emits")
an [Approval](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20)
event.
### Fn transferFrom[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-transferfrom "Direct link to Fn transferFrom")
function transferFrom( address sender, address recipient, uint256 amount) external returns (bool)
_Moves `amount` tokens from `sender` to `recipient` using the allowance mechanism. `amount` is then deducted from the caller's allowance._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-7 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `sender` | address | |
| `recipient` | address | |
| `amount` | uint256 | |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#return-values-2 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `[0]` | bool | Returns Success a boolean value indicating whether the operation succeeded. |
#### Emits[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#emits-2 "Direct link to Emits")
a [Transfer](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20)
event.
### Fn increaseAllowance[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-increaseallowance "Direct link to Fn increaseAllowance")
function increaseAllowance( address spender, uint256 addedValue) external returns (bool)
\_Atomically increases the allowance granted to `spender` by the caller.
This is an alternative to `approve` that can be used as a mitigation for problems described in [IERC20-approve](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20)
.\_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-8 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `spender` | address | |
| `addedValue` | uint256 | |
#### Emits[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#emits-3 "Direct link to Emits")
an [Approval](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20)
event indicating the updated allowance.
@custom:requirements
* \`spender\` cannot be the zero address.
### Fn decreaseAllowance[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-decreaseallowance "Direct link to Fn decreaseAllowance")
function decreaseAllowance( address spender, uint256 subtractedValue) external returns (bool)
\_Atomically decreases the allowance granted to `spender` by the caller.
This is an alternative to approve that can be used as a mitigation for problems described in [IERC20-approve](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20)
.\_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-9 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `spender` | address | |
| `subtractedValue` | uint256 | |
#### Emits[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#emits-4 "Direct link to Emits")
an [Approval](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20)
event indicating the updated allowance.
@custom:requirements
* \`spender\` cannot be the zero address.
* \`spender\` must have allowance for the caller of at least \`subtractedValue\`.
### Fn granularity[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-granularity "Direct link to Fn granularity")
function granularity() external returns (uint256)
_Returns the smallest part of the token that is not divisible. This means all token operations (creation, movement and destruction) must have amounts that are a multiple of this number._
#### Note[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#note-2 "Direct link to Note")
For super token contracts, this value is always 1
### Fn send[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-send "Direct link to Fn send")
function send( address recipient, uint256 amount, bytes userData) external
\_Moves `amount` tokens from the caller's account to `recipient`.
If send or receive hooks are registered for the caller and `recipient`, the corresponding functions will be called with `userData` and empty `operatorData`. See [IERC777Sender](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20)
and [IERC777Recipient](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20)
.\_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-10 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `recipient` | address | |
| `amount` | uint256 | |
| `userData` | bytes | |
#### Emits[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#emits-5 "Direct link to Emits")
a [Sent](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20)
event.
@custom:requirements
* the caller must have at least \`amount\` tokens.
* \`recipient\` cannot be the zero address.
* if \`recipient\` is a contract, it must implement the [IERC777Recipient](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20)
interface.
### Fn burn[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-burn "Direct link to Fn burn")
function burn( uint256 amount, bytes userData) external
\_Destroys `amount` tokens from the caller's account, reducing the total supply and transfers the underlying token to the caller's account.
If a send hook is registered for the caller, the corresponding function will be called with `userData` and empty `operatorData`. See [IERC777Sender](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20)
.\_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-11 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `amount` | uint256 | |
| `userData` | bytes | |
#### Emits[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#emits-6 "Direct link to Emits")
a [Burned](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20)
event.
@custom:requirements
* the caller must have at least \`amount\` tokens.
### Fn isOperatorFor[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-isoperatorfor "Direct link to Fn isOperatorFor")
function isOperatorFor( address operator, address tokenHolder) external returns (bool)
\_Returns true if an account is an operator of `tokenHolder`. Operators can send and burn tokens on behalf of their owners. All accounts are their own operator.
See [operatorSend](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20)
and [operatorBurn](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20)
.\_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-12 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `operator` | address | |
| `tokenHolder` | address | |
### Fn authorizeOperator[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-authorizeoperator "Direct link to Fn authorizeOperator")
function authorizeOperator( address operator) external
\_Make an account an operator of the caller.
See [isOperatorFor](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20)
.\_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-13 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `operator` | address | |
#### Emits[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#emits-7 "Direct link to Emits")
an [AuthorizedOperator](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20)
event.
@custom:requirements
* \`operator\` cannot be calling address.
### Fn revokeOperator[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-revokeoperator "Direct link to Fn revokeOperator")
function revokeOperator( address operator) external
\_Revoke an account's operator status for the caller.
See [isOperatorFor](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20)
and [defaultOperators](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20)
.\_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-14 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `operator` | address | |
#### Emits[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#emits-8 "Direct link to Emits")
a [RevokedOperator](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20)
event.
@custom:requirements
* \`operator\` cannot be calling address.
### Fn defaultOperators[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-defaultoperators "Direct link to Fn defaultOperators")
function defaultOperators() external returns (address[])
\_Returns the list of default operators. These accounts are operators for all token holders, even if [authorizeOperator](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20)
was never called on them.
This list is immutable, but individual holders may revoke these via [revokeOperator](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20)
, in which case [isOperatorFor](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20)
will return false.\_
### Fn operatorSend[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-operatorsend "Direct link to Fn operatorSend")
function operatorSend( address sender, address recipient, uint256 amount, bytes userData, bytes operatorData) external
\_Moves `amount` tokens from `sender` to `recipient`. The caller must be an operator of `sender`.
If send or receive hooks are registered for `sender` and `recipient`, the corresponding functions will be called with `userData` and `operatorData`. See [IERC777Sender](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20)
and [IERC777Recipient](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20)
.\_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-15 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `sender` | address | |
| `recipient` | address | |
| `amount` | uint256 | |
| `userData` | bytes | |
| `operatorData` | bytes | |
#### Emits[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#emits-9 "Direct link to Emits")
a [Sent](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20)
event.
@custom:requirements
* \`sender\` cannot be the zero address.
* \`sender\` must have at least \`amount\` tokens.
* the caller must be an operator for \`sender\`.
* \`recipient\` cannot be the zero address.
* if \`recipient\` is a contract, it must implement the [IERC777Recipient](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20)
interface.
### Fn operatorBurn[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-operatorburn "Direct link to Fn operatorBurn")
function operatorBurn( address account, uint256 amount, bytes userData, bytes operatorData) external
\_Destroys `amount` tokens from `account`, reducing the total supply. The caller must be an operator of `account`.
If a send hook is registered for `account`, the corresponding function will be called with `userData` and `operatorData`. See [IERC777Sender](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20)
.\_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-16 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `account` | address | |
| `amount` | uint256 | |
| `userData` | bytes | |
| `operatorData` | bytes | |
#### Emits[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#emits-10 "Direct link to Emits")
a [Burned](https://docs.openzeppelin.com/contracts/2.x/api/token/erc20#IERC20)
event.
@custom:requirements
* \`account\` cannot be the zero address.
* \`account\` must have at least \`amount\` tokens.
* the caller must be an operator for \`account\`.
### Fn selfMint[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-selfmint "Direct link to Fn selfMint")
function selfMint( address account, uint256 amount, bytes userData) external
\_Mint new tokens for the account If `userData` is not empty, the `tokensReceived` hook is invoked according to ERC777 semantics.
@custom:modifiers
* onlySelf\_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-17 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `account` | address | |
| `amount` | uint256 | |
| `userData` | bytes | |
### Fn selfBurn[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-selfburn "Direct link to Fn selfBurn")
function selfBurn( address account, uint256 amount, bytes userData) external
\_Burn existing tokens for the account If `userData` is not empty, the `tokensToSend` hook is invoked according to ERC777 semantics.
@custom:modifiers
* onlySelf\_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-18 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `account` | address | |
| `amount` | uint256 | |
| `userData` | bytes | |
### Fn selfTransferFrom[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-selftransferfrom "Direct link to Fn selfTransferFrom")
function selfTransferFrom( address sender, address spender, address recipient, uint256 amount) external
\_Transfer `amount` tokens from the `sender` to `recipient`. If `spender` isn't the same as `sender`, checks if `spender` has allowance to spend tokens of `sender`.
@custom:modifiers
* onlySelf\_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-19 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `sender` | address | |
| `spender` | address | |
| `recipient` | address | |
| `amount` | uint256 | |
### Fn selfApproveFor[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-selfapprovefor "Direct link to Fn selfApproveFor")
function selfApproveFor( address account, address spender, uint256 amount) external
\_Give `spender`, `amount` allowance to spend the tokens of `account`.
@custom:modifiers
* onlySelf\_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-20 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `account` | address | |
| `spender` | address | |
| `amount` | uint256 | |
### Fn transferAll[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-transferall "Direct link to Fn transferAll")
function transferAll( address recipient) external
_Transfer all available balance from `msg.sender` to `recipient`_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-21 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `recipient` | address | |
### Fn getUnderlyingToken[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-getunderlyingtoken "Direct link to Fn getUnderlyingToken")
function getUnderlyingToken() external returns (address tokenAddr)
_Return the underlying token contract_
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#return-values-3 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `tokenAddr` | address | Underlying token address |
### Fn getUnderlyingDecimals[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-getunderlyingdecimals "Direct link to Fn getUnderlyingDecimals")
function getUnderlyingDecimals() external returns (uint8 underlyingDecimals)
_Return the underlying token decimals_
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#return-values-4 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `underlyingDecimals` | uint8 | Underlying token decimals |
### Fn toUnderlyingAmount[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-tounderlyingamount "Direct link to Fn toUnderlyingAmount")
function toUnderlyingAmount( uint256 amount) external returns (uint256 underlyingAmount, uint256 adjustedAmount)
_Return the underlying token conversion rate_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-22 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `amount` | uint256 | Number of tokens to be upgraded (in 18 decimals) |
#### Return Values[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#return-values-5 "Direct link to Return Values")
| Name | Type | Description |
| --- | --- | --- |
| `underlyingAmount` | uint256 | The underlying token amount after scaling |
| `adjustedAmount` | uint256 | The super token amount after scaling |
### Fn upgrade[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-upgrade "Direct link to Fn upgrade")
function upgrade( uint256 amount) external
_Upgrade ERC20 to SuperToken._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-23 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `amount` | uint256 | Number of tokens to be upgraded (in 18 decimals) |
#### Note[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#note-3 "Direct link to Note")
It will use \`transferFrom\` to get tokens. Before calling this function you should \`approve\` this contract
### Fn upgradeTo[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-upgradeto "Direct link to Fn upgradeTo")
function upgradeTo( address to, uint256 amount, bytes userData) external
_Upgrade ERC20 to SuperToken and transfer immediately_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-24 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `to` | address | The account to receive upgraded tokens |
| `amount` | uint256 | Number of tokens to be upgraded (in 18 decimals) |
| `userData` | bytes | User data for the TokensRecipient callback |
#### Note[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#note-4 "Direct link to Note")
It will use \`transferFrom\` to get tokens. Before calling this function you should \`approve\` this contract
@custom:warning
* there is potential of reentrancy IF the "to" account is a registered ERC777 recipient. @custom:requirements
* if \`userData\` is NOT empty AND \`to\` is a contract, it MUST be a registered ERC777 recipient otherwise it reverts.
### Fn downgrade[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-downgrade "Direct link to Fn downgrade")
function downgrade( uint256 amount) external
_Downgrade SuperToken to ERC20. It will call transfer to send tokens_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-25 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `amount` | uint256 | Number of tokens to be downgraded |
### Fn downgradeTo[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-downgradeto "Direct link to Fn downgradeTo")
function downgradeTo( address to, uint256 amount) external
_Downgrade SuperToken to ERC20 and transfer immediately_
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-26 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `to` | address | The account to receive downgraded tokens |
| `amount` | uint256 | Number of tokens to be downgraded (in 18 decimals) |
### Fn operationApprove[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-operationapprove "Direct link to Fn operationApprove")
function operationApprove( address account, address spender, uint256 amount) external
_Perform ERC20 approve by host contract._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-27 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `account` | address | The account owner to be approved. |
| `spender` | address | The spender of account owner's funds. |
| `amount` | uint256 | Number of tokens to be approved. |
@custom:modifiers
* onlyHost |
### Fn operationIncreaseAllowance[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-operationincreaseallowance "Direct link to Fn operationIncreaseAllowance")
function operationIncreaseAllowance( address account, address spender, uint256 addedValue) external
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-28 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `account` | address | |
| `spender` | address | |
| `addedValue` | uint256 | |
### Fn operationDecreaseAllowance[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-operationdecreaseallowance "Direct link to Fn operationDecreaseAllowance")
function operationDecreaseAllowance( address account, address spender, uint256 subtractedValue) external
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-29 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `account` | address | |
| `spender` | address | |
| `subtractedValue` | uint256 | |
### Fn operationTransferFrom[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-operationtransferfrom "Direct link to Fn operationTransferFrom")
function operationTransferFrom( address account, address spender, address recipient, uint256 amount) external
_Perform ERC20 transferFrom by host contract._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-30 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `account` | address | The account to spend sender's funds. |
| `spender` | address | The account where the funds is sent from. |
| `recipient` | address | The recipient of the funds. |
| `amount` | uint256 | Number of tokens to be transferred. |
@custom:modifiers
* onlyHost |
### Fn operationSend[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-operationsend "Direct link to Fn operationSend")
function operationSend( address spender, address recipient, uint256 amount, bytes userData) external
_Perform ERC777 send by host contract._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-31 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `spender` | address | The account where the funds is sent from. |
| `recipient` | address | The recipient of the funds. |
| `amount` | uint256 | Number of tokens to be transferred. |
| `userData` | bytes | Arbitrary user inputted data |
@custom:modifiers
* onlyHost |
### Fn operationUpgrade[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-operationupgrade "Direct link to Fn operationUpgrade")
function operationUpgrade( address account, uint256 amount) external
_Upgrade ERC20 to SuperToken by host contract._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-32 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `account` | address | The account to be changed. |
| `amount` | uint256 | Number of tokens to be upgraded (in 18 decimals) |
@custom:modifiers
* onlyHost |
### Fn operationDowngrade[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-operationdowngrade "Direct link to Fn operationDowngrade")
function operationDowngrade( address account, uint256 amount) external
_Downgrade ERC20 to SuperToken by host contract._
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-33 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `account` | address | The account to be changed. |
| `amount` | uint256 | Number of tokens to be downgraded (in 18 decimals) |
@custom:modifiers
* onlyHost |
Events[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#events "Direct link to Events")
-----------------------------------------------------------------------------------------------------------
### Event AdminChanged[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#event-adminchanged "Direct link to Event AdminChanged")
event AdminChanged( address oldAdmin, address newAdmin)
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-34 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `oldAdmin` | address | |
| `newAdmin` | address | |
### Event TokenUpgraded[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#event-tokenupgraded "Direct link to Event TokenUpgraded")
event TokenUpgraded( address account, uint256 amount)
Token upgrade event
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-35 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `account` | address | Account where tokens are upgraded to |
| `amount` | uint256 | Amount of tokens upgraded (in 18 decimals) |
### Event TokenDowngraded[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#event-tokendowngraded "Direct link to Event TokenDowngraded")
event TokenDowngraded( address account, uint256 amount)
Token downgrade event
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-36 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `account` | address | Account whose tokens are downgraded |
| `amount` | uint256 | Amount of tokens downgraded |
### Event ConstantOutflowNFTCreated[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#event-constantoutflownftcreated "Direct link to Event ConstantOutflowNFTCreated")
event ConstantOutflowNFTCreated( contract IConstantOutflowNFT constantOutflowNFT)
Constant Outflow NFT proxy created event
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-37 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `constantOutflowNFT` | contract IConstantOutflowNFT | constant outflow nft address |
### Event ConstantInflowNFTCreated[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#event-constantinflownftcreated "Direct link to Event ConstantInflowNFTCreated")
event ConstantInflowNFTCreated( contract IConstantInflowNFT constantInflowNFT)
Constant Inflow NFT proxy created event
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-38 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `constantInflowNFT` | contract IConstantInflowNFT | constant inflow nft address |
### Event PoolAdminNFTCreated[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#event-pooladminnftcreated "Direct link to Event PoolAdminNFTCreated")
event PoolAdminNFTCreated( contract IPoolAdminNFT poolAdminNFT)
Pool Admin NFT proxy created event
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-39 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `poolAdminNFT` | contract IPoolAdminNFT | pool admin nft address |
### Event PoolMemberNFTCreated[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#event-poolmembernftcreated "Direct link to Event PoolMemberNFTCreated")
event PoolMemberNFTCreated( contract IPoolMemberNFT poolMemberNFT)
Pool Member NFT proxy created event
#### Parameters[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#parameters-40 "Direct link to Parameters")
| Name | Type | Description |
| --- | --- | --- |
| `poolMemberNFT` | contract IPoolMemberNFT | pool member nft address |
Error Codes[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#error-codes "Direct link to Error Codes")
--------------------------------------------------------------------------------------------------------------------------
### SUPER\_TOKEN\_CALLER\_IS\_NOT\_OPERATOR\_FOR\_HOLDER[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#super_token_caller_is_not_operator_for_holder "Direct link to SUPER_TOKEN_CALLER_IS_NOT_OPERATOR_FOR_HOLDER")
error SUPER_TOKEN_CALLER_IS_NOT_OPERATOR_FOR_HOLDER()
### SUPER\_TOKEN\_NOT\_ERC777\_TOKENS\_RECIPIENT[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#super_token_not_erc777_tokens_recipient "Direct link to SUPER_TOKEN_NOT_ERC777_TOKENS_RECIPIENT")
error SUPER_TOKEN_NOT_ERC777_TOKENS_RECIPIENT()
### SUPER\_TOKEN\_INFLATIONARY\_DEFLATIONARY\_NOT\_SUPPORTED[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#super_token_inflationary_deflationary_not_supported "Direct link to SUPER_TOKEN_INFLATIONARY_DEFLATIONARY_NOT_SUPPORTED")
error SUPER_TOKEN_INFLATIONARY_DEFLATIONARY_NOT_SUPPORTED()
### SUPER\_TOKEN\_NO\_UNDERLYING\_TOKEN[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#super_token_no_underlying_token "Direct link to SUPER_TOKEN_NO_UNDERLYING_TOKEN")
error SUPER_TOKEN_NO_UNDERLYING_TOKEN()
### SUPER\_TOKEN\_ONLY\_SELF[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#super_token_only_self "Direct link to SUPER_TOKEN_ONLY_SELF")
error SUPER_TOKEN_ONLY_SELF()
### SUPER\_TOKEN\_ONLY\_ADMIN[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#super_token_only_admin "Direct link to SUPER_TOKEN_ONLY_ADMIN")
error SUPER_TOKEN_ONLY_ADMIN()
### SUPER\_TOKEN\_ONLY\_GOV\_OWNER[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#super_token_only_gov_owner "Direct link to SUPER_TOKEN_ONLY_GOV_OWNER")
error SUPER_TOKEN_ONLY_GOV_OWNER()
### SUPER\_TOKEN\_APPROVE\_FROM\_ZERO\_ADDRESS[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#super_token_approve_from_zero_address "Direct link to SUPER_TOKEN_APPROVE_FROM_ZERO_ADDRESS")
error SUPER_TOKEN_APPROVE_FROM_ZERO_ADDRESS()
### SUPER\_TOKEN\_APPROVE\_TO\_ZERO\_ADDRESS[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#super_token_approve_to_zero_address "Direct link to SUPER_TOKEN_APPROVE_TO_ZERO_ADDRESS")
error SUPER_TOKEN_APPROVE_TO_ZERO_ADDRESS()
### SUPER\_TOKEN\_BURN\_FROM\_ZERO\_ADDRESS[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#super_token_burn_from_zero_address "Direct link to SUPER_TOKEN_BURN_FROM_ZERO_ADDRESS")
error SUPER_TOKEN_BURN_FROM_ZERO_ADDRESS()
### SUPER\_TOKEN\_MINT\_TO\_ZERO\_ADDRESS[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#super_token_mint_to_zero_address "Direct link to SUPER_TOKEN_MINT_TO_ZERO_ADDRESS")
error SUPER_TOKEN_MINT_TO_ZERO_ADDRESS()
### SUPER\_TOKEN\_TRANSFER\_FROM\_ZERO\_ADDRESS[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#super_token_transfer_from_zero_address "Direct link to SUPER_TOKEN_TRANSFER_FROM_ZERO_ADDRESS")
error SUPER_TOKEN_TRANSFER_FROM_ZERO_ADDRESS()
### SUPER\_TOKEN\_TRANSFER\_TO\_ZERO\_ADDRESS[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#super_token_transfer_to_zero_address "Direct link to SUPER_TOKEN_TRANSFER_TO_ZERO_ADDRESS")
error SUPER_TOKEN_TRANSFER_TO_ZERO_ADDRESS()
### SUPER\_TOKEN\_NFT\_PROXY\_ADDRESS\_CHANGED[](https://docs.superfluid.org/docs/technical-reference/ISuperToken#super_token_nft_proxy_address_changed "Direct link to SUPER_TOKEN_NFT_PROXY_ADDRESS_CHANGED")
error SUPER_TOKEN_NFT_PROXY_ADDRESS_CHANGED()
* [Implementation addresses](https://docs.superfluid.org/docs/technical-reference/ISuperToken#implementation-addresses)
* [ABI](https://docs.superfluid.org/docs/technical-reference/ISuperToken#abi)
* [Functions](https://docs.superfluid.org/docs/technical-reference/ISuperToken#functions)
* [Fn initialize](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-initialize)
* [Fn initializeWithAdmin](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-initializewithadmin)
* [Fn changeAdmin](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-changeadmin)
* [Fn getAdmin](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-getadmin)
* [Fn CONSTANT\_OUTFLOW\_NFT](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-constant_outflow_nft)
* [Fn CONSTANT\_INFLOW\_NFT](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-constant_inflow_nft)
* [Fn POOL\_ADMIN\_NFT](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-pool_admin_nft)
* [Fn POOL\_MEMBER\_NFT](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-pool_member_nft)
* [Fn name](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-name)
* [Fn symbol](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-symbol)
* [Fn decimals](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-decimals)
* [Fn totalSupply](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-totalsupply)
* [Fn balanceOf](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-balanceof)
* [Fn transfer](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-transfer)
* [Fn allowance](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-allowance)
* [Fn approve](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-approve)
* [Fn transferFrom](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-transferfrom)
* [Fn increaseAllowance](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-increaseallowance)
* [Fn decreaseAllowance](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-decreaseallowance)
* [Fn granularity](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-granularity)
* [Fn send](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-send)
* [Fn burn](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-burn)
* [Fn isOperatorFor](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-isoperatorfor)
* [Fn authorizeOperator](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-authorizeoperator)
* [Fn revokeOperator](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-revokeoperator)
* [Fn defaultOperators](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-defaultoperators)
* [Fn operatorSend](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-operatorsend)
* [Fn operatorBurn](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-operatorburn)
* [Fn selfMint](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-selfmint)
* [Fn selfBurn](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-selfburn)
* [Fn selfTransferFrom](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-selftransferfrom)
* [Fn selfApproveFor](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-selfapprovefor)
* [Fn transferAll](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-transferall)
* [Fn getUnderlyingToken](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-getunderlyingtoken)
* [Fn getUnderlyingDecimals](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-getunderlyingdecimals)
* [Fn toUnderlyingAmount](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-tounderlyingamount)
* [Fn upgrade](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-upgrade)
* [Fn upgradeTo](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-upgradeto)
* [Fn downgrade](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-downgrade)
* [Fn downgradeTo](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-downgradeto)
* [Fn operationApprove](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-operationapprove)
* [Fn operationIncreaseAllowance](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-operationincreaseallowance)
* [Fn operationDecreaseAllowance](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-operationdecreaseallowance)
* [Fn operationTransferFrom](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-operationtransferfrom)
* [Fn operationSend](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-operationsend)
* [Fn operationUpgrade](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-operationupgrade)
* [Fn operationDowngrade](https://docs.superfluid.org/docs/technical-reference/ISuperToken#fn-operationdowngrade)
* [Events](https://docs.superfluid.org/docs/technical-reference/ISuperToken#events)
* [Event AdminChanged](https://docs.superfluid.org/docs/technical-reference/ISuperToken#event-adminchanged)
* [Event TokenUpgraded](https://docs.superfluid.org/docs/technical-reference/ISuperToken#event-tokenupgraded)
* [Event TokenDowngraded](https://docs.superfluid.org/docs/technical-reference/ISuperToken#event-tokendowngraded)
* [Event ConstantOutflowNFTCreated](https://docs.superfluid.org/docs/technical-reference/ISuperToken#event-constantoutflownftcreated)
* [Event ConstantInflowNFTCreated](https://docs.superfluid.org/docs/technical-reference/ISuperToken#event-constantinflownftcreated)
* [Event PoolAdminNFTCreated](https://docs.superfluid.org/docs/technical-reference/ISuperToken#event-pooladminnftcreated)
* [Event PoolMemberNFTCreated](https://docs.superfluid.org/docs/technical-reference/ISuperToken#event-poolmembernftcreated)
* [Error Codes](https://docs.superfluid.org/docs/technical-reference/ISuperToken#error-codes)
* [SUPER\_TOKEN\_CALLER\_IS\_NOT\_OPERATOR\_FOR\_HOLDER](https://docs.superfluid.org/docs/technical-reference/ISuperToken#super_token_caller_is_not_operator_for_holder)
* [SUPER\_TOKEN\_NOT\_ERC777\_TOKENS\_RECIPIENT](https://docs.superfluid.org/docs/technical-reference/ISuperToken#super_token_not_erc777_tokens_recipient)
* [SUPER\_TOKEN\_INFLATIONARY\_DEFLATIONARY\_NOT\_SUPPORTED](https://docs.superfluid.org/docs/technical-reference/ISuperToken#super_token_inflationary_deflationary_not_supported)
* [SUPER\_TOKEN\_NO\_UNDERLYING\_TOKEN](https://docs.superfluid.org/docs/technical-reference/ISuperToken#super_token_no_underlying_token)
* [SUPER\_TOKEN\_ONLY\_SELF](https://docs.superfluid.org/docs/technical-reference/ISuperToken#super_token_only_self)
* [SUPER\_TOKEN\_ONLY\_ADMIN](https://docs.superfluid.org/docs/technical-reference/ISuperToken#super_token_only_admin)
* [SUPER\_TOKEN\_ONLY\_GOV\_OWNER](https://docs.superfluid.org/docs/technical-reference/ISuperToken#super_token_only_gov_owner)
* [SUPER\_TOKEN\_APPROVE\_FROM\_ZERO\_ADDRESS](https://docs.superfluid.org/docs/technical-reference/ISuperToken#super_token_approve_from_zero_address)
* [SUPER\_TOKEN\_APPROVE\_TO\_ZERO\_ADDRESS](https://docs.superfluid.org/docs/technical-reference/ISuperToken#super_token_approve_to_zero_address)
* [SUPER\_TOKEN\_BURN\_FROM\_ZERO\_ADDRESS](https://docs.superfluid.org/docs/technical-reference/ISuperToken#super_token_burn_from_zero_address)
* [SUPER\_TOKEN\_MINT\_TO\_ZERO\_ADDRESS](https://docs.superfluid.org/docs/technical-reference/ISuperToken#super_token_mint_to_zero_address)
* [SUPER\_TOKEN\_TRANSFER\_FROM\_ZERO\_ADDRESS](https://docs.superfluid.org/docs/technical-reference/ISuperToken#super_token_transfer_from_zero_address)
* [SUPER\_TOKEN\_TRANSFER\_TO\_ZERO\_ADDRESS](https://docs.superfluid.org/docs/technical-reference/ISuperToken#super_token_transfer_to_zero_address)
* [SUPER\_TOKEN\_NFT\_PROXY\_ADDRESS\_CHANGED](https://docs.superfluid.org/docs/technical-reference/ISuperToken#super_token_nft_proxy_address_changed)
---
# Guides | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/category/guides#__docusaurus_skipToContent_fallback)
[🗃️ Deploy a Super Token\
------------------------\
\
3 items](https://docs.superfluid.org/docs/category/deploy-a-super-token)
[📄️ Using the SuperTokenV1Library\
---------------------------------\
\
The SuperTokenV1Library is the primary interface for developers to interact with the Superfluid protocol](https://docs.superfluid.org/docs/protocol/super-tokens/guides/using-library)
---
# Guides | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/category/guides-2#__docusaurus_skipToContent_fallback)
[📄️ How to Design your Distribution Pools?\
------------------------------------------\
\
In this page we will explain Distribution Pools and show you the most relevant ways to interact with them through the Super Token interface.](https://docs.superfluid.org/docs/protocol/distributions/guides/pools)
[📄️ Create, Update and Connect your Pools\
-----------------------------------------\
\
Building on top of the Superfluid's Distribution Pools protocol involves interacting with Super Tokens. Remember, Superfluid is a token-centric protocol, and all of the primitives are centered around Super Tokens.](https://docs.superfluid.org/docs/protocol/distributions/guides/on-chain)
[📄️ Testing\
-----------\
\
In this guide, we'll walk through the process of testing the DistributionContract using the Foundry framework. This guide follows the structure used for the Superfluid contract, adapting to the specifics of the DistributionContract.](https://docs.superfluid.org/docs/protocol/distributions/guides/testing)
---
# Guides | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/category/guides-1#__docusaurus_skipToContent_fallback)
[📄️ Control Flows\
-----------------\
\
This guide covers various methods for managing flows directly on the Superfluid protocol. It includes creating, updating, and deleting flows, on chain, from another smart contracts.](https://docs.superfluid.org/docs/protocol/money-streaming/guides/create-update-delete-flow)
[📄️ Manage Access Control and User Data\
---------------------------------------\
\
This page provides an overview of how to manage access control and user data in the Superfluid protocol.](https://docs.superfluid.org/docs/protocol/money-streaming/guides/acl-user-data)
[📄️ Testing\
-----------\
\
In this guide, we'll walk through the process of testing a Superfluid contract using the Foundry framework. We'll use the FlowSender contract described in the Quickstart as our example to demonstrate how to write effective tests.](https://docs.superfluid.org/docs/protocol/money-streaming/guides/testing)
---
# Examples | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/category/examples#__docusaurus_skipToContent_fallback)
[📄️ FlowSplitter Smart Contract\
-------------------------------\
\
This guide provides an overview and usage instructions for the FlowSplitter smart contract, which leverages the Superfluid protocol to route incoming streams of Super Tokens to two different recipients based on predefined proportions.](https://docs.superfluid.org/docs/protocol/money-streaming/examples/example1)
---
# Testing | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/protocol/distributions/guides/testing#__docusaurus_skipToContent_fallback)
On this page
In this guide, we'll walk through the process of testing the `DistributionContract` using the Foundry framework. This guide follows the structure used for the `Superfluid` contract, adapting to the specifics of the `DistributionContract`.
Prerequisites[](https://docs.superfluid.org/docs/protocol/distributions/guides/testing#prerequisites "Direct link to Prerequisites")
--------------------------------------------------------------------------------------------------------------------------------------
Before diving into testing your Superfluid contracts with Foundry, make sure you have set up your development environment properly. Here's a brief explanation of each step required:
1. **Creating and Navigating to Your Project Directory**:
mkdir superfluid-example && cd superfluid-example
This command creates a new directory named `foundry-example` and then changes your current working directory to it.
2. **Initializing a Foundry Project**:
forge init
This initializes a new Foundry project in your directory, setting up the necessary structure and configuration for Ethereum smart contract development.
3. **Installing Superfluid Protocol Dependencies**:
forge install superfluid-protocol-monorepo=https://github.com/superfluid-finance/protocol-monorepo --no-commit
Installs the `dev` branch of the Superfluid protocol from its GitHub repository.
4. **Installing OpenZeppelin Contracts**:
forge install https://github.com/OpenZeppelin/openzeppelin-contracts@v4.9.6 --no-commit
Installs the necessary (4.9.X) of the OpenZeppelin contracts, which are widely used for secure smart contract development.
These steps ensure you have the necessary tools and dependencies installed to start developing and testing your Superfluid-based contracts with Foundry.
Contract and Key Functions[](https://docs.superfluid.org/docs/protocol/distributions/guides/testing#contract-and-key-functions "Direct link to Contract and Key Functions")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Click here to show `DistributionContract`
//SPDX-License-Identifier: Unlicensedpragma solidity ^0.8.14;import { ISuperfluid, ISuperToken } from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol";import { SuperTokenV1Library } from "@superfluid-finance/ethereum-contracts/contracts/apps/SuperTokenV1Library.sol";import {IGeneralDistributionAgreementV1, ISuperfluidPool, PoolConfig} from "@superfluid-finance/ethereum-contracts/contracts/interfaces/agreements/gdav1/IGeneralDistributionAgreementV1.sol";import "@openzeppelin/contracts/token/ERC20/IERC20.sol";interface IFakeDAI is IERC20 { function mint(address account, uint256 amount) external;}contract DistributionContract { using SuperTokenV1Library for ISuperToken; mapping (address => bool) public accountList; ISuperToken public daix; ISuperfluidPool pool; // fDAIx address on Polygon Mumbai = 0x5D8B4C2554aeB7e86F387B4d6c00Ac33499Ed01f constructor(ISuperToken _daix) { daix = _daix; } /// @dev Mints 10,000 fDAI to this contract and wraps it all into fDAIx function gainDaiX() external { // Get address of fDAI by getting underlying token address from DAIx token IFakeDAI fdai = IFakeDAI( daix.getUnderlyingToken() ); // Mint 10,000 fDAI fdai.mint(address(this), 10000e18); // Approve fDAIx contract to spend fDAI fdai.approve(address(daix), 20000e18); // Wrap the fDAI into fDAIx daix.upgrade(10000e18); } /// @dev creates a Pool with this contract being the admin function createPool(ISuperToken token, PoolConfig memory poolConfig) external { // Create Pool pool=daix.createPool(token, address(this), poolConfig); } /// @dev updates Units for a specific member function updateMemberUnits(address memberAddress, uint128 newUnits) external { // Update member units pool.updateMemberUnits(memberAddress, newUnits); } /// @dev creates a stream from this contract to the pool function createStreamToPool(int96 flowRate) external { // Create stream daix.createFlow(receiver, flowRate); }}
* **gainDaiX**: Mints and wraps fDAI into fDAIx.
* **createPool**: Initiates a new Superfluid pool with this contract as the admin.
* **updateMemberUnits**: Updates units for a specific pool member.
* **createStreamToPool**: Creates a money stream from this contract to the pool.
Writing Tests[](https://docs.superfluid.org/docs/protocol/distributions/guides/testing#writing-tests "Direct link to Writing Tests")
--------------------------------------------------------------------------------------------------------------------------------------
### Setting Up Your Test Environment[](https://docs.superfluid.org/docs/protocol/distributions/guides/testing#setting-up-your-test-environment "Direct link to Setting Up Your Test Environment")
Your test environment will depend on where you would like to test your Superfluid application. You can fork a public testnet where an instance of the Superfluid Protocol already exists (e.g Polygon Mumbai). In this case, you do not need to deploy a new instance of the Superfluid protocol. However, if you are testing on a local testnet you would need to deploy a new instance of the Superfluid protocol.
* Forking Testnet
* Local Net
* Create a new Solidity file for your tests
* Import `forge-std/Test.sol` and inherit from `Test`.
* Import the Superfluid protocol contracts.
* Write your `setUp` function to run before each test case.
pragma solidity ^0.8.14;import "forge-std/Test.sol";import {ISuperfluid, ISuperToken} from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol";import {TestGovernance, Superfluid, ConstantFlowAgreementV1, CFAv1Library, SuperTokenFactory} from "@superfluid-finance/ethereum-contracts/contracts/utils/SuperfluidFrameworkDeploymentSteps.sol";import {SuperfluidFrameworkDeployer} from "@superfluid-finance/ethereum-contracts/contracts/utils/SuperfluidFrameworkDeployer.sol";import {SuperTokenV1Library} from "@superfluid-finance/ethereum-contracts/contracts/apps/SuperTokenV1Library.sol";contract DistributionContractTest is Test { // Test contract instance DistributionContract distributionContract; // Mumbai fork parameters uint256 mumbaiFork; // Set up your environment variables and include MUMBAI_RPC_URL string MUMBAI_RPC_URL = vm.envString("MUMBAI_RPC_URL"); // Setup function to initialize test environment function setUp() public { //Forking and selecting the Mumbai testnet mumbaiFork = vm.createSelectFork(MUMBAI_RPC_URL); //Pointing to the fake Daix contract on Mumbai //For token and protocol addresses on all networks, check out the Superfluid Explorer: https://Explorer.superfluid.finance/ daix = ISuperToken(0x5D8B4C2554aeB7e86F387B4d6c00Ac33499Ed01f); //Deploy the contract vm.prank(address(0x123)); // Simulate a different caller distributionContract= new DistributionContract(daix); vm.unprank(); // Restore the caller //Add other functions and test contracts... }}
* Create a new Solidity file for your test.
* Import `forge-std/Test.sol` and inherit from `Test`.
* Import the Superfluid protocol contracts.
* Deploy a new instance of the Superfluid Protocol in the `setUp`function.
* Create and Deploy a new instance of your test contract.
pragma solidity ^0.8.14;import "forge-std/Test.sol";import {ISuperfluid} from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol";import {SuperfluidFrameworkDeployer, TestGovernance, Superfluid, ConstantFlowAgreementV1, CFAv1Library, SuperTokenFactory} from "@superfluid-finance/ethereum-contracts/contracts/utils/SuperfluidFrameworkDeployer.sol";contract DistributionContractTest is Test { // Test contract instance DistributionContract distributionContract; //Set up your Superfluid framework struct Framework { TestGovernance governance; Superfluid host; ConstantFlowAgreementV1 cfa; CFAv1Library.InitData cfaLib; InstantDistributionAgreementV1 ida; IDAv1Library.InitData idaLib; SuperTokenFactory superTokenFactory; } SuperfluidFrameworkDeployer.Framework sf; // Setup function to initialize test environment function setUp() public { address public owner; //DEPLOYING THE FRAMEWORK SuperfluidFrameworkDeployer sfDeployer = new SuperfluidFrameworkDeployer(); sfDeployer.deployFramework(); sf = sfDeployer.getFramework(); // DEPLOYING DAI and DAI wrapper super token ISuperToken daix = sfDeployer.deployWrapperToken( "Fake DAI", "DAI", 18, 10000000000000 ); // Deploy your contract here distributionContract= new DistributionContract(daix); }}
About the `setUp` Function
The `setUp` function is an **optional** function standardized by Foundry (but it is necessary here, especially in the case of local testnet). It is a special function that is executed before each test case. It is used to initialize the test environment and contract instances. To learn more about the `setUp` function, check out the [Foundry documentation](https://book.getfoundry.sh/forge/writing-tests)
.
### Testing Contract Functions[](https://docs.superfluid.org/docs/protocol/distributions/guides/testing#testing-contract-functions "Direct link to Testing Contract Functions")
#### GainDaiX Function[](https://docs.superfluid.org/docs/protocol/distributions/guides/testing#gaindaix-function "Direct link to GainDaiX Function")
The `gainDaiX` function mints and wraps fDAI into fDAIx. Here's how to test it:
function testGainDaiX() public { // Setup: Deploy the DistributionContract with a mock fDAIx token ISuperToken daix = new MockSuperToken(); DistributionContract distributionContract = new DistributionContract(daix); // Action: Call the gainDaiX function distributionContract.gainDaiX(); // Assertions: Check if the contract has the expected amount of fDAIx uint256 balance = daix.balanceOf(address(distributionContract)); assertEq(balance, 10000e18, "The balance of fDAIx should be 10,000 after gainDaiX");}
#### CreatePool Function[](https://docs.superfluid.org/docs/protocol/distributions/guides/testing#createpool-function "Direct link to CreatePool Function")
To test `createPool`, you'll verify if a pool is created with the correct parameters:
function testCreatePool() public { // Setup: Deploy the DistributionContract and mock tokens ISuperToken daix = new MockSuperToken(); DistributionContract distributionContract = new DistributionContract(daix); // Define pool configuration PoolConfig memory poolConfig; // Set poolConfig parameters... // Action: Call the createPool function distributionContract.createPool(daix, poolConfig); // Assertions: Verify if the pool is created correctly ISuperfluidPool pool = distributionContract.pool(); // Additional assertions about pool...}
#### UpdateMemberUnits Function[](https://docs.superfluid.org/docs/protocol/distributions/guides/testing#updatememberunits-function "Direct link to UpdateMemberUnits Function")
Testing `updateMemberUnits` involves checking if member units in a pool are updated correctly:
function testUpdateMemberUnits() public { // Setup: Deploy the DistributionContract, create a pool, and add members ISuperToken daix = new MockSuperToken(); DistributionContract distributionContract = new DistributionContract(daix); // Create pool... address memberAddress = address(new Member()); // Action: Update member units uint128 newUnits = 100; distributionContract.updateMemberUnits(memberAddress, newUnits); // Assertions: Check if the member's units are updated uint128 updatedUnits = daix.getMemberUnits(memberAddress); assertEq(updatedUnits, newUnits, "Member units should be updated to the new value");}
#### CreateStreamToPool Function[](https://docs.superfluid.org/docs/protocol/distributions/guides/testing#createstreamtopool-function "Direct link to CreateStreamToPool Function")
For `createStreamToPool`, you'll need to ensure that a stream is correctly established:
function testCreateStreamToPool() public { // Setup: Deploy the DistributionContract and create a pool ISuperToken daix = new MockSuperToken(); DistributionContract distributionContract = new DistributionContract(daix); // Create pool... // Action: Create a stream to the pool int96 flowRate = 1000; distributionContract.createStreamToPool(flowRate); // Assertions: Verify the stream is created with the correct flow rate // Implement checks for stream creation...}
### Using Cheat Codes[](https://docs.superfluid.org/docs/protocol/distributions/guides/testing#using-cheat-codes "Direct link to Using Cheat Codes")
Foundry's cheat codes can simulate various scenarios. Here's an example of using a cheat code to test access control:
function testUnauthorizedAccess() public { // Setup: Deploy the DistributionContract DistributionContract distributionContract = new DistributionContract(...); // Use cheat codes to simulate an unauthorized user vm.prank(address(0x123)); vm.expectRevert("Unauthorized access"); // Attempt to call a function that requires specific permissions distributionContract.someFunctionRequiringAuthorization();}## Running TestsExecute your tests using the following command:```bashforge test
Best Practices[](https://docs.superfluid.org/docs/protocol/distributions/guides/testing#best-practices "Direct link to Best Practices")
-----------------------------------------------------------------------------------------------------------------------------------------
* Write clear, descriptive test cases.
* Maintain code readability.
* Use Foundry cheat codes for simulating real-world scenarios.
* Aim for high test coverage.
Conclusion[](https://docs.superfluid.org/docs/protocol/distributions/guides/testing#conclusion "Direct link to Conclusion")
-----------------------------------------------------------------------------------------------------------------------------
Testing ensures the reliability and security of blockchain contracts. This guide provides a foundational approach for using Foundry to test the `DistributionContract`.
Further Resources[](https://docs.superfluid.org/docs/protocol/distributions/guides/testing#further-resources "Direct link to Further Resources")
--------------------------------------------------------------------------------------------------------------------------------------------------
* [Foundry Book](https://foundry.readthedocs.io/)
* [Prerequisites](https://docs.superfluid.org/docs/protocol/distributions/guides/testing#prerequisites)
* [Contract and Key Functions](https://docs.superfluid.org/docs/protocol/distributions/guides/testing#contract-and-key-functions)
* [Writing Tests](https://docs.superfluid.org/docs/protocol/distributions/guides/testing#writing-tests)
* [Setting Up Your Test Environment](https://docs.superfluid.org/docs/protocol/distributions/guides/testing#setting-up-your-test-environment)
* [Testing Contract Functions](https://docs.superfluid.org/docs/protocol/distributions/guides/testing#testing-contract-functions)
* [Using Cheat Codes](https://docs.superfluid.org/docs/protocol/distributions/guides/testing#using-cheat-codes)
* [Best Practices](https://docs.superfluid.org/docs/protocol/distributions/guides/testing#best-practices)
* [Conclusion](https://docs.superfluid.org/docs/protocol/distributions/guides/testing#conclusion)
* [Further Resources](https://docs.superfluid.org/docs/protocol/distributions/guides/testing#further-resources)
---
# Create, Update and Connect your Pools | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/protocol/distributions/guides/on-chain#__docusaurus_skipToContent_fallback)
On this page
Building on top of the Superfluid's Distribution Pools protocol involves interacting with Super Tokens. Remember, Superfluid is a token-centric protocol, and all of the primitives are centered around [Super Tokens](https://docs.superfluid.org/docs/protocol/super-tokens/overview)
. Distribution Pools allow for scalable and efficient one-to-many token distributions at a fixed gas cost.
When interacting with Super Tokens on-chain, you can use the Superfluid's [SuperTokenV1Library](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library)
to access the core functions.
About the General Distributions Agreement
At times, we use "Distribution Pools" or the "General Distributions Agreement" (GDA) interchangeably. The GDA is the name of the implementation in our codebase. If you are interested in the technical details, you can find the full Superfluid Architecture [here](https://docs.superfluid.org/docs/technical-reference/Architecture)
.
Importance of Distribution Pools[](https://docs.superfluid.org/docs/protocol/distributions/guides/on-chain#importance-of-distribution-pools "Direct link to Importance of Distribution Pools")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Distribution Pools are at the core of Superfluid's functionality, enabling a multitude of applications such as subscription services, salary payments, and rewards distribution. They are designed to be flexible, allowing for both instant and streaming distributions.
* **Instant Distributions**: Allow for a one-time distribution of a specified amount of tokens to all members of a pool instantly.
* **Streaming Distributions**: Enable a continuous flow of tokens to pool members over time.
About Pools
The same pool can be used to distribute any Super Token, be it for Instant or Streaming Distributions.
Key Functions of SuperTokenV1Library.sol[](https://docs.superfluid.org/docs/protocol/distributions/guides/on-chain#key-functions-of-supertokenv1librarysol "Direct link to Key Functions of SuperTokenV1Library.sol")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
[`SuperTokenV1Library.sol`](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library)
provides several functions to interact with pools and distributions:
### createPool[](https://docs.superfluid.org/docs/protocol/distributions/guides/on-chain#createpool "Direct link to createPool")
function createPool(ISuperToken token, address admin, struct PoolConfig poolConfig) internal returns (contract ISuperfluidPool pool)// simplified variant using the following default settings:// admin = msg.sender, poolConfig = { transferabilityForUnitsOwner: false, distributionFromAnyAddress: true }function createPool(contract ISuperToken token) internal returns (contract ISuperfluidPool pool);
Creates a new Superfluid Distribution Pool.
### distribute[](https://docs.superfluid.org/docs/protocol/distributions/guides/on-chain#distribute "Direct link to distribute")
function distribute(ISuperToken token, ISuperfluidPool pool, uint256 amount) internal returns (bool)
Distributes the specified amount of tokens among pool members.
### distributeFlow[](https://docs.superfluid.org/docs/protocol/distributions/guides/on-chain#distributeflow "Direct link to distributeFlow")
function distributeFlow(ISuperToken token, ISuperfluidPool pool, int96 requestedFlowRate) internal returns (bool)
Initiates a distribution flow from a sender to a pool with the specified total flow rate.
Important
Keep in mind that the total amount of units in the pool needs to be significantly lower than the total flow rate or the total tokens distributed of the pool. To understand more why this is the case, please refer to the [Member Units](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#about-member-units)
section.
### connectPool[](https://docs.superfluid.org/docs/protocol/distributions/guides/on-chain#connectpool "Direct link to connectPool")
function connectPool(ISuperToken token, contract ISuperfluidPool pool) internal returns (bool)
Connects a pool member to pool.
About Pool Connections
Learn more about claiming units and connecting to pools in the [How to design your pools section](https://docs.superfluid.org/docs/protocol/distributions/guides/pools#about-pool-connections-and-claiming)
.
### getFlowDistributionFlowRate[](https://docs.superfluid.org/docs/protocol/distributions/guides/on-chain#getflowdistributionflowrate "Direct link to getFlowDistributionFlowRate")
function getFlowDistributionFlowRate(ISuperToken token, address from, ISuperfluidPool to) internal view returns (int96)
Gets the flow rate of a distribution from a sender to a pool.
### isMemberConnected[](https://docs.superfluid.org/docs/protocol/distributions/guides/on-chain#ismemberconnected "Direct link to isMemberConnected")
function isMemberConnected(ISuperToken token, address pool, address member) internal view returns (bool)
Checks whether a member is connected to a pool and eligible to receive distributions.
ISuperfluidPool[](https://docs.superfluid.org/docs/protocol/distributions/guides/on-chain#isuperfluidpool "Direct link to ISuperfluidPool")
---------------------------------------------------------------------------------------------------------------------------------------------
### updateMemberUnits[](https://docs.superfluid.org/docs/protocol/distributions/guides/on-chain#updatememberunits "Direct link to updateMemberUnits")
function updateMemberUnits(address memberAddress, uint128 newUnits) internal returns (bool)
Updates the units of a pool member.
Contract Example[](https://docs.superfluid.org/docs/protocol/distributions/guides/on-chain#contract-example "Direct link to Contract Example")
------------------------------------------------------------------------------------------------------------------------------------------------
Here's a simple contract example using some of the functions from `SuperTokenV1Library.sol` to interact with distributions:
// SPDX-License-Identifier: MITpragma solidity ^0.8.0;import "@superfluid-finance/ethereum-contracts/contracts/superfluid/SuperTokenV1Library.sol";contract MyDistributionsContract { using SuperTokenV1Library for ISuperToken; ISuperToken private _superToken; constructor(ISuperToken superToken) { _superToken = superToken; } function estimateDistribution(ISuperfluidPool pool, uint256 amount) public { _superToken.estimateDistributionActualAmount(address(this), pool, amount); // Additional logic for distribution } function startStreamingDistribution(ISuperfluidPool pool, int96 flowRate) public { _superToken.distributeFlow(pool, flowRate); // Additional logic for streaming distribution }}
This contract demonstrates how to use the `SuperTokenV1Library` in order to interact with Distribution Pools.
tip
When using the `SuperTokenV1Library.sol`, you don't need to include the `SuperToken` as a parameter in your method call. Simply call `SuperToken.[Method]` and the library will handle the rest.
Further Reading[](https://docs.superfluid.org/docs/protocol/distributions/guides/on-chain#further-reading "Direct link to Further Reading")
---------------------------------------------------------------------------------------------------------------------------------------------
For more detailed information on the implementation and usage of `SuperTokenV1Library.sol`, refer to the [SuperTokenV1Library Technical reference](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library)
.
* [Importance of Distribution Pools](https://docs.superfluid.org/docs/protocol/distributions/guides/on-chain#importance-of-distribution-pools)
* [Key Functions of SuperTokenV1Library.sol](https://docs.superfluid.org/docs/protocol/distributions/guides/on-chain#key-functions-of-supertokenv1librarysol)
* [createPool](https://docs.superfluid.org/docs/protocol/distributions/guides/on-chain#createpool)
* [distribute](https://docs.superfluid.org/docs/protocol/distributions/guides/on-chain#distribute)
* [distributeFlow](https://docs.superfluid.org/docs/protocol/distributions/guides/on-chain#distributeflow)
* [connectPool](https://docs.superfluid.org/docs/protocol/distributions/guides/on-chain#connectpool)
* [getFlowDistributionFlowRate](https://docs.superfluid.org/docs/protocol/distributions/guides/on-chain#getflowdistributionflowrate)
* [isMemberConnected](https://docs.superfluid.org/docs/protocol/distributions/guides/on-chain#ismemberconnected)
* [ISuperfluidPool](https://docs.superfluid.org/docs/protocol/distributions/guides/on-chain#isuperfluidpool)
* [updateMemberUnits](https://docs.superfluid.org/docs/protocol/distributions/guides/on-chain#updatememberunits)
* [Contract Example](https://docs.superfluid.org/docs/protocol/distributions/guides/on-chain#contract-example)
* [Further Reading](https://docs.superfluid.org/docs/protocol/distributions/guides/on-chain#further-reading)
---
# Testing | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/protocol/money-streaming/guides/testing#__docusaurus_skipToContent_fallback)
On this page
In this guide, we'll walk through the process of testing a Superfluid contract using the Foundry framework. We'll use the `FlowSender` contract described in the [Quickstart](https://docs.superfluid.org/docs/protocol/quickstart)
as our example to demonstrate how to write effective tests.
Prerequisites[](https://docs.superfluid.org/docs/protocol/money-streaming/guides/testing#prerequisites "Direct link to Prerequisites")
----------------------------------------------------------------------------------------------------------------------------------------
Before diving into testing your Superfluid contracts with Foundry, make sure you have set up your development environment properly. Here's a brief explanation of each step required:
1. **Creating and Navigating to Your Project Directory**:
mkdir superfluid-example && cd superfluid-example
This command creates a new directory named `foundry-example` and then changes your current working directory to it.
2. **Initializing a Foundry Project**:
forge init
This initializes a new Foundry project in your directory, setting up the necessary structure and configuration for Ethereum smart contract development.
3. **Installing Superfluid Protocol Dependencies**:
forge install superfluid-protocol-monorepo=https://github.com/superfluid-finance/protocol-monorepo --no-commit
Installs the `dev` branch of the Superfluid protocol from its GitHub repository.
4. **Installing OpenZeppelin Contracts**:
forge install https://github.com/OpenZeppelin/openzeppelin-contracts@v4.9.6 --no-commit
Installs the necessary (4.9.X) of the OpenZeppelin contracts, which are widely used for secure smart contract development.
These steps ensure you have the necessary tools and dependencies installed to start developing and testing your Superfluid-based contracts with Foundry.
Contract and Key Functions[](https://docs.superfluid.org/docs/protocol/money-streaming/guides/testing#contract-and-key-functions "Direct link to Contract and Key Functions")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Click here to show `FlowSender` contract
//SPDX-License-Identifier: Unlicensedpragma solidity ^0.8.14;import { ISuperfluid, ISuperToken } from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol";import { SuperTokenV1Library } from "@superfluid-finance/ethereum-contracts/contracts/apps/SuperTokenV1Library.sol";import "@openzeppelin/contracts/token/ERC20/IERC20.sol";// For deployment on Mumbai Testnetinterface IFakeDAI is IERC20 { function mint(address account, uint256 amount) external;}contract FlowSender { using SuperTokenV1Library for ISuperToken; mapping (address => bool) public accountList; ISuperToken public daix; // fDAIx address on Polygon Mumbai = 0x5D8B4C2554aeB7e86F387B4d6c00Ac33499Ed01f constructor(ISuperToken _daix) { daix = _daix; } /// @dev Mints 10,000 fDAI to this contract and wraps it all into fDAIx function gainDaiX() external { // Get address of fDAI by getting underlying token address from DAIx token IFakeDAI fdai = IFakeDAI( daix.getUnderlyingToken() ); // Mint 10,000 fDAI fdai.mint(address(this), 10000e18); // Approve fDAIx contract to spend fDAI fdai.approve(address(daix), 20000e18); // Wrap the fDAI into fDAIx daix.upgrade(10000e18); } /// @dev creates a stream from this contract to desired receiver at desired rate function createStream(int96 flowRate, address receiver) external { // Create stream daix.createFlow(receiver, flowRate); } /// @dev updates a stream from this contract to desired receiver to desired rate function updateStream(int96 flowRate, address receiver) external { // Update stream daix.updateFlow(receiver, flowRate); } /// @dev deletes a stream from this contract to desired receiver function deleteStream(address receiver) external { // Delete stream daix.deleteFlow(address(this), receiver); } /// @dev get flow rate between this contract to certain receiver function readFlowRate(address receiver) external view returns (int96 flowRate) { // Get flow rate return daix.getFlowRate(address(this), receiver); }}
* **gainDaiX**: Mints and wraps fDAI into fDAIx (Superfluid's wrapped token).
* **createStream**: Initiates a new money stream to a specified receiver.
* **updateStream**: Updates an existing money stream's flow rate.
* **deleteStream**: Terminates an existing money stream.
* **readFlowRate**: Reads the current flow rate of a stream.
Writing Tests[](https://docs.superfluid.org/docs/protocol/money-streaming/guides/testing#writing-tests "Direct link to Writing Tests")
----------------------------------------------------------------------------------------------------------------------------------------
### Setting Up Your Test Environment[](https://docs.superfluid.org/docs/protocol/money-streaming/guides/testing#setting-up-your-test-environment "Direct link to Setting Up Your Test Environment")
Your test environment will depend on where you would like to test your Superfluid application. You can fork a public testnet where an instance of the Superfluid Protocol already exists (e.g Polygon Mumbai). In this case, you do not need to deploy a new instance of the Superfluid protocol. However, if you are testing on a local testnet you would need to deploy a new instance of the Superfluid protocol.
* Forked Testnet
* Local Net
* Create a new Solidity file for your tests
* Import `forge-std/Test.sol` and inherit from `Test`.
* Import the Superfluid protocol contracts.
* Write your `setUp` function to run before each test case.
pragma solidity ^0.8.14;import "forge-std/Test.sol";import {ISuperfluid, ISuperToken} from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol";import {TestGovernance, Superfluid, ConstantFlowAgreementV1, CFAv1Library, SuperTokenFactory} from "@superfluid-finance/ethereum-contracts/contracts/utils/SuperfluidFrameworkDeploymentSteps.sol";import {SuperfluidFrameworkDeployer} from "@superfluid-finance/ethereum-contracts/contracts/utils/SuperfluidFrameworkDeployer.sol";import {SuperTokenV1Library} from "@superfluid-finance/ethereum-contracts/contracts/apps/SuperTokenV1Library.sol";contract FlowSenderTest is Test { // Test contract instance FlowSender flowSender; // Mumbai fork parameters uint256 mumbaiFork; // Set up your environment variables and include MUMBAI_RPC_URL string MUMBAI_RPC_URL = vm.envString("MUMBAI_RPC_URL"); // Setup function to initialize test environment function setUp() public { //Forking and selecting the Mumbai testnet mumbaiFork = vm.createSelectFork(MUMBAI_RPC_URL); //Pointing to the fake Daix contract on Mumbai //For token and protocol addresses on all networks, check out the Superfluid Explorer: https://Explorer.superfluid.finance/ daix = ISuperToken(0x5D8B4C2554aeB7e86F387B4d6c00Ac33499Ed01f); //Deploy the contract vm.prank(address(0x123)); // Simulate a different caller flowSender=new FlowSender(daix); vm.unprank(); // Restore the caller //Add other functions and test contracts... }}
* Create a new Solidity file for your test.
* Import `forge-std/Test.sol` and inherit from `Test`.
* Import the Superfluid protocol contracts.
* Deploy a new instance of the Superfluid Protocol in the `setUp` function.
* Create and Deploy a new instance of your test contract.
pragma solidity ^0.8.14;import "forge-std/Test.sol";import {ISuperfluid} from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol";import {SuperfluidFrameworkDeployer, TestGovernance, Superfluid, ConstantFlowAgreementV1, CFAv1Library, SuperTokenFactory} from "@superfluid-finance/ethereum-contracts/contracts/utils/SuperfluidFrameworkDeployer.sol";contract FlowSenderTest is Test { // Test contract instance FlowSender flowSender; //Set up your Superfluid framework struct Framework { TestGovernance governance; Superfluid host; ConstantFlowAgreementV1 cfa; CFAv1Library.InitData cfaLib; InstantDistributionAgreementV1 ida; IDAv1Library.InitData idaLib; SuperTokenFactory superTokenFactory; } SuperfluidFrameworkDeployer.Framework sf; // Setup function to initialize test environment function setUp() public { address public owner; //DEPLOYING THE FRAMEWORK SuperfluidFrameworkDeployer sfDeployer = new SuperfluidFrameworkDeployer(); sfDeployer.deployTestFramework(); sf = sfDeployer.getFramework(); // DEPLOYING DAI and DAI wrapper super token ISuperToken daix = sfDeployer.deployWrapperToken( "Fake DAI", "DAI", 18, 10000000000000 ); // Initialize your contract here flowSender = new FlowSender( daix ); }}
About the `setUp` Function
The `setUp` function is an **optional** function standardized by Foundry (but it is necessary here, especially in the case of local testnet). It is a special function that is executed before each test case. It is used to initialize the test environment and contract instances. To learn more about the `setUp` function, check out the [Foundry documentation](https://book.getfoundry.sh/forge/writing-tests)
.
### Testing Contract Functions[](https://docs.superfluid.org/docs/protocol/money-streaming/guides/testing#testing-contract-functions "Direct link to Testing Contract Functions")
#### GainDaiX Function[](https://docs.superfluid.org/docs/protocol/money-streaming/guides/testing#gaindaix-function "Direct link to GainDaiX Function")
Let's write a test for the `gainDaiX` function in the `FlowSender` contract:
function testGainDaiX() public { // Setup: Deploy the FlowSender contract IFakeDAI fdai = new FakeDAI(); ISuperToken daix = new SuperToken(address(fdai)); FlowSender flowSender = new FlowSender(daix); // Action: Call the gainDaiX function flowSender.gainDaiX(); // Assertions: Check if the contract has the expected amount of DAIx uint256 balance = daix.balanceOf(address(flowSender)); assertEq(balance, 10000e18, "The balance of DAIx should be 10,000 after gainDaiX");}
#### CreateStream Function[](https://docs.superfluid.org/docs/protocol/money-streaming/guides/testing#createstream-function "Direct link to CreateStream Function")
Now, let's test the `createStream` function:
function testCreateStream() public { // Setup: Deploy the FlowSender contract and create a receiver address IFakeDAI fdai = new FakeDAI(); ISuperToken daix = new SuperToken(address(fdai)); FlowSender flowSender = new FlowSender(daix); address receiver = address(new Receiver()); // Setup: Define a flow rate int96 flowRate = 1000; // Example flow rate // Action: Call the createStream function flowSender.createStream(flowRate, receiver); // Assertions: Verify if the stream is created with correct parameters (,int96 outFlowRate,,) = daix.getFlow(address(flowSender), receiver); assertEq(outFlowRate, flowRate, "The flow rate should match the specified rate");}
### Using Cheat Codes[](https://docs.superfluid.org/docs/protocol/money-streaming/guides/testing#using-cheat-codes "Direct link to Using Cheat Codes")
Foundry's cheat codes can simulate various blockchain states and interactions. For example, to test the `deleteStream` function, you might want to simulate different account permissions:
function testDeleteStream() public { // Setup: Deploy the FlowSender contract and create a receiver address IFakeDAI fdai = new FakeDAI(); ISuperToken daix = new SuperToken(address(fdai)); FlowSender flowSender = new FlowSender(daix); address receiver = address(new Receiver()); // Setup: Create a stream first flowSender.createStream(1000, receiver); // Use cheat codes to simulate different account permissions // Attempt to delete a stream with an unauthorized user vm.prank(address(0x123)); // Simulate a different caller vm.expectRevert("Unauthorized"); // Expect a revert due to unauthorized access flowSender.deleteStream(receiver); // Action: Attempt to delete a stream with the correct permission flowSender.deleteStream(receiver); // Assertions: Verify the stream is deleted (,int96 outFlowRate,,) = daix.getFlow(address(flowSender), receiver); assertEq(outFlowRate, 0, "The flow rate should be zero after deletion");}
Running Tests[](https://docs.superfluid.org/docs/protocol/money-streaming/guides/testing#running-tests "Direct link to Running Tests")
----------------------------------------------------------------------------------------------------------------------------------------
To execute your tests, use:
forge test
Best Practices[](https://docs.superfluid.org/docs/protocol/money-streaming/guides/testing#best-practices "Direct link to Best Practices")
-------------------------------------------------------------------------------------------------------------------------------------------
* Write clear and descriptive test cases.
* Ensure code readability for easier maintenance.
* Use Foundry cheat codes to simulate real-world scenarios.
* Strive for high test coverage to capture a wide range of use cases.
Conclusion[](https://docs.superfluid.org/docs/protocol/money-streaming/guides/testing#conclusion "Direct link to Conclusion")
-------------------------------------------------------------------------------------------------------------------------------
Testing is crucial in blockchain development for ensuring contract reliability and security, especially for complex protocols like Superfluid. This guide provides a foundation for using Foundry to write and run effective tests.
Further Resources[](https://docs.superfluid.org/docs/protocol/money-streaming/guides/testing#further-resources "Direct link to Further Resources")
----------------------------------------------------------------------------------------------------------------------------------------------------
* [Foundry Book](https://foundry.readthedocs.io/)
* [Prerequisites](https://docs.superfluid.org/docs/protocol/money-streaming/guides/testing#prerequisites)
* [Contract and Key Functions](https://docs.superfluid.org/docs/protocol/money-streaming/guides/testing#contract-and-key-functions)
* [Writing Tests](https://docs.superfluid.org/docs/protocol/money-streaming/guides/testing#writing-tests)
* [Setting Up Your Test Environment](https://docs.superfluid.org/docs/protocol/money-streaming/guides/testing#setting-up-your-test-environment)
* [Testing Contract Functions](https://docs.superfluid.org/docs/protocol/money-streaming/guides/testing#testing-contract-functions)
* [Using Cheat Codes](https://docs.superfluid.org/docs/protocol/money-streaming/guides/testing#using-cheat-codes)
* [Running Tests](https://docs.superfluid.org/docs/protocol/money-streaming/guides/testing#running-tests)
* [Best Practices](https://docs.superfluid.org/docs/protocol/money-streaming/guides/testing#best-practices)
* [Conclusion](https://docs.superfluid.org/docs/protocol/money-streaming/guides/testing#conclusion)
* [Further Resources](https://docs.superfluid.org/docs/protocol/money-streaming/guides/testing#further-resources)
---
# Manage Access Control and User Data | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/sdk/money-streaming/acl-user-data#__docusaurus_skipToContent_fallback)
On this page
This guide explains how to manage access control and user data in the Superfluid protocol from your client applications:
* Access control allows you to delegate flow management to another account
* User data lets you attach additional information to transactions.
Interacting with the Superfluid Protocol[](https://docs.superfluid.org/docs/sdk/money-streaming/acl-user-data#interacting-with-the-superfluid-protocol "Direct link to Interacting with the Superfluid Protocol")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
To interact with the Superfluid protocol from client applications, you'll use the [`CFAv1Forwarder`](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder)
contract. In the case of a JavaScript/TypeScript based application, here's how to set it up:
### Contract ABI and Address[](https://docs.superfluid.org/docs/sdk/money-streaming/acl-user-data#contract-abi-and-address "Direct link to Contract ABI and Address")
The `CFAv1Forwarder` contract address is the same on all networks:
0xcfA132E353cB4E398080B9700609bb008eceB125
You can find the full ABI of the `CFAv1Forwarder` contract in the [CFAv1Forwarder technical reference](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder)
.
### Setting up with ethers.js[](https://docs.superfluid.org/docs/sdk/money-streaming/acl-user-data#setting-up-with-ethersjs "Direct link to Setting up with ethers.js")
Here's how to initiate interaction with the `CFAv1Forwarder` contract using ethers.js:
import { ethers } from 'ethers';// Assuming you have a provider set up (e.g., using MetaMask)const provider = new ethers.providers.Web3Provider(window.ethereum);// The address of the CFAv1Forwarder contractconst forwarderAddress = '0xcfA132E353cB4E398080B9700609bb008eceB125';// The ABI of the CFAv1Forwarder contract (import this from the technical reference)const forwarderABI = [...]; // Insert the ABI here// Create a contract instanceconst forwarderContract = new ethers.Contract(forwarderAddress, forwarderABI, provider.getSigner());
Access Control in Superfluid[](https://docs.superfluid.org/docs/sdk/money-streaming/acl-user-data#access-control-in-superfluid "Direct link to Access Control in Superfluid")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Access control in Superfluid allows one account (the flow operator) to manage flows on behalf of another account. This is particularly useful for automated systems, multi-sig wallets, or any scenario where you want to delegate flow management.
Key concepts:
* **Flow Operator**: An account that has been granted permissions to manage flows on behalf of another account.
* **Permissions**: The specific actions a flow operator is allowed to perform (create, update, delete flows).
* **Flow Rate Allowance**: The maximum net flow rate a flow operator can create on behalf of the account.
User Data in Superfluid[](https://docs.superfluid.org/docs/sdk/money-streaming/acl-user-data#user-data-in-superfluid "Direct link to User Data in Superfluid")
----------------------------------------------------------------------------------------------------------------------------------------------------------------
User data in Superfluid allows you to attach additional information to transactions. This can be used for various purposes:
* Including metadata with transactions
* Triggering specific logic in receiver contracts
* Implementing off-chain systems that react to on-chain events
User data is typically passed as a `bytes` parameter in Superfluid functions, allowing you to encode any type of data you need.
Key Functions for Access Control (with User Data)[](https://docs.superfluid.org/docs/sdk/money-streaming/acl-user-data#key-functions-for-access-control-with-user-data "Direct link to Key Functions for Access Control (with User Data)")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
### grantPermissions[](https://docs.superfluid.org/docs/sdk/money-streaming/acl-user-data#grantpermissions "Direct link to grantPermissions")
Grants permissions to a flow operator to manage flows on behalf of the caller.
function grantPermissions( ISuperToken token, address flowOperator) external returns (bool)
#### Parameters[](https://docs.superfluid.org/docs/sdk/money-streaming/acl-user-data#parameters "Direct link to Parameters")
* `token`: The Super Token address
* `flowOperator`: The account to which permissions are granted
#### Usage Example[](https://docs.superfluid.org/docs/sdk/money-streaming/acl-user-data#usage-example "Direct link to Usage Example")
const grantPermissions = async (tokenAddress, flowOperatorAddress) => { try { const tx = await forwarderContract.grantPermissions(tokenAddress, flowOperatorAddress); await tx.wait(); console.log("Permissions granted successfully!"); } catch (error) { console.error("Error granting permissions:", error); }};
### revokePermissions[](https://docs.superfluid.org/docs/sdk/money-streaming/acl-user-data#revokepermissions "Direct link to revokePermissions")
Revokes all permissions previously granted to a flow operator.
function revokePermissions( ISuperToken token, address flowOperator) external returns (bool)
#### Parameters[](https://docs.superfluid.org/docs/sdk/money-streaming/acl-user-data#parameters-1 "Direct link to Parameters")
* `token`: The Super Token address
* `flowOperator`: The account from which permissions are revoked
#### Usage Example[](https://docs.superfluid.org/docs/sdk/money-streaming/acl-user-data#usage-example-1 "Direct link to Usage Example")
const revokePermissions = async (tokenAddress, flowOperatorAddress) => { try { const tx = await forwarderContract.revokePermissions(tokenAddress, flowOperatorAddress); await tx.wait(); console.log("Permissions revoked successfully!"); } catch (error) { console.error("Error revoking permissions:", error); }};
### setFlowrateFrom[](https://docs.superfluid.org/docs/sdk/money-streaming/acl-user-data#setflowratefrom "Direct link to setFlowrateFrom")
Allows a flow operator to set the flow rate from one account to another.
function setFlowrateFrom( ISuperToken token, address sender, address receiver, int96 flowrate) external returns (bool)
#### Parameters[](https://docs.superfluid.org/docs/sdk/money-streaming/acl-user-data#parameters-2 "Direct link to Parameters")
* `token`: The Super Token address
* `sender`: The sender of the flow
* `receiver`: The receiver of the flow
* `flowrate`: The desired flow rate in tokens per second (using 18 decimal places)
#### Usage Example[](https://docs.superfluid.org/docs/sdk/money-streaming/acl-user-data#usage-example-2 "Direct link to Usage Example")
const setFlowrateFrom = async (tokenAddress, senderAddress, receiverAddress, flowRate) => { try { const tx = await forwarderContract.setFlowrateFrom(tokenAddress, senderAddress, receiverAddress, flowRate); await tx.wait(); console.log("Flow rate set successfully!"); } catch (error) { console.error("Error setting flow rate:", error); }};
Live UI Example for Access Control List Management[](https://docs.superfluid.org/docs/sdk/money-streaming/acl-user-data#live-ui-example-for-access-control-list-management "Direct link to Live UI Example for Access Control List Management")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Here's an example of a UI component for managing access control lists:
Live Editor
function AccessControlManager() {
const \[tokenAddress, setTokenAddress\] \= useState(''); const \[flowOperator, setFlowOperator\] \= useState(''); const \[sender, setSender\] \= useState(''); const \[receiver, setReceiver\] \= useState(''); const \[flowRate, setFlowRate\] \= useState(''); const \[walletConnected, setWalletConnected\] \= useState(false); const \[account, setAccount\] \= useState(''); const toast \= useToast();
const forwarderAddress \= '0xcfA132E353cB4E398080B9700609bb008eceB125'; const forwarderABI \= CFAv1ForwarderABI; // You will need to import the ABI in your code. You can do that from: https://docs.superfluid.finance/docs/technical-reference/CFAv1Forwarder
const connectWallet \= async () \=> { if (typeof window.ethereum !== 'undefined') { try { await window.ethereum.request({ method: 'eth\_requestAccounts' }); const provider \= new ethers.providers.Web3Provider(window.ethereum); const signer \= provider.getSigner(); const address \= await signer.getAddress(); setAccount(address); setWalletConnected(true); toast({ title: 'Wallet connected', description: \`Connected to ${address}\`, status: 'success', duration: 3000, isClosable: true, }); } catch (error) { console.error('Failed to connect wallet:', error); toast({ title: 'Connection failed', description: 'Failed to connect wallet. Please try again.', status: 'error', duration: 3000, isClosable: true, }); } } else { toast({ title: 'Metamask not detected', description: 'Please install Metamask to use this feature.', status: 'warning', duration: 3000, isClosable: true, }); } };
const handleAction \= async (action) \=> { if (!walletConnected) { toast({ title: 'Wallet not connected', description: 'Please connect your wallet first.', status: 'warning', duration: 3000, isClosable: true, }); return; }
const provider \= new ethers.providers.Web3Provider(window.ethereum); const signer \= provider.getSigner(); const contract \= new ethers.Contract(forwarderAddress, forwarderABI, signer);
try { let tx; switch (action) { case 'grant': tx \= await contract.grantPermissions(tokenAddress, flowOperator); break; case 'revoke': tx \= await contract.revokePermissions(tokenAddress, flowOperator); break; case 'setFlowrate': tx \= await contract.setFlowrateFrom(tokenAddress, sender, receiver, flowRate); break; } await tx.wait(); toast({ title: 'Transaction successful', description: \`${action} action completed successfully!\`, status: 'success', duration: 3000, isClosable: true, }); } catch (error) { console.error(\`Error performing ${action} action:\`, error); toast({ title: 'Transaction failed', description: \`Failed to ${action}. Please try again.\`, status: 'error', duration: 3000, isClosable: true, }); } };
return ( Access Control Manager
{!walletConnected ? ( ) : ( Connected: {account} )}
setTokenAddress(e.target.value)} /> setFlowOperator(e.target.value)} /> setSender(e.target.value)} /> setReceiver(e.target.value)} /> setFlowRate(e.target.value)} />
);
}
Result
Loading...
This UI provides the following features:
1. **Wallet Connection**: Users can connect their Ethereum wallet to interact with the Superfluid protocol.
2. **Input Fields**: Users can enter the token address, flow operator address, sender address, receiver address, and flow rate.
3. **Action Buttons**: Separate buttons for granting permissions, revoking permissions, and setting flow rate.
4. **Feedback**: Toast notifications to inform users about the success or failure of their actions.
To use this component:
1. Click "Connect Wallet" to connect your Ethereum wallet.
2. Enter the required information in the input fields.
3. Click the appropriate button to perform the desired action (grant permissions, revoke permissions, or set flow rate).
This example provides a starting point for building a user interface to manage access control in Superfluid. In a production environment, you would want to add more robust error checking, input validation, and possibly additional features like displaying current permissions or flow rates.
the example does not work on your developer environment?
The example above is a live example and requires the ABI to be imported. In the case of this example, the ABI has already been imported through the live coder.
In order to make it work on your developer environment, head to the [CFAv1Forwarder technical reference](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder)
and copy the ABI. Then, replace the `forwarderABI` variable in the example with the ABI you copied.
* [Interacting with the Superfluid Protocol](https://docs.superfluid.org/docs/sdk/money-streaming/acl-user-data#interacting-with-the-superfluid-protocol)
* [Contract ABI and Address](https://docs.superfluid.org/docs/sdk/money-streaming/acl-user-data#contract-abi-and-address)
* [Setting up with ethers.js](https://docs.superfluid.org/docs/sdk/money-streaming/acl-user-data#setting-up-with-ethersjs)
* [Access Control in Superfluid](https://docs.superfluid.org/docs/sdk/money-streaming/acl-user-data#access-control-in-superfluid)
* [User Data in Superfluid](https://docs.superfluid.org/docs/sdk/money-streaming/acl-user-data#user-data-in-superfluid)
* [Key Functions for Access Control (with User Data)](https://docs.superfluid.org/docs/sdk/money-streaming/acl-user-data#key-functions-for-access-control-with-user-data)
* [grantPermissions](https://docs.superfluid.org/docs/sdk/money-streaming/acl-user-data#grantpermissions)
* [revokePermissions](https://docs.superfluid.org/docs/sdk/money-streaming/acl-user-data#revokepermissions)
* [setFlowrateFrom](https://docs.superfluid.org/docs/sdk/money-streaming/acl-user-data#setflowratefrom)
* [Live UI Example for Access Control List Management](https://docs.superfluid.org/docs/sdk/money-streaming/acl-user-data#live-ui-example-for-access-control-list-management)
---
# Manage Access Control and User Data | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/protocol/money-streaming/guides/acl-user-data#__docusaurus_skipToContent_fallback)
On this page
This page provides an overview of how to manage access control and user data in the Superfluid protocol. We will show how to use the [SuperTokenV1Library](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library)
to interact with the protocol and demonstrate how to grant permissions, create flows, and attach user data to transactions within your smart contracts.
Introduction to SuperTokenV1Library[](https://docs.superfluid.org/docs/protocol/money-streaming/guides/acl-user-data#introduction-to-supertokenv1library "Direct link to Introduction to SuperTokenV1Library")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
The [SuperTokenV1Library](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library)
is the primary interface for developers to interact with the Superfluid protocol when building smart contracts on-chain. It provides a comprehensive set of tools for working with [Money Streaming](https://docs.superfluid.org/docs/protocol/money-streaming/overview)
(_Constant Flow Agreement - CFA_) and [Distribution Pools](https://docs.superfluid.org/docs/protocol/distributions/overview)
(_General Distributions Agreement - GDA_).
To use the SuperTokenV1Library in your smart contract:
1. Import the library:
import "@superfluid-finance/ethereum-contracts/contracts/apps/SuperTokenV1Library.sol";
2. Include the `using` statement:
using SuperTokenV1Library for ISuperToken;
Learn more about the SuperTokenV1Library
For more details on the SuperTokenV1Library, refer to the page [Using the SuperTokenV1Library](https://docs.superfluid.org/docs/protocol/super-tokens/guides/using-library)
. For a full list of its functions, refer to its [technical reference](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library)
.
Access Control in Superfluid[](https://docs.superfluid.org/docs/protocol/money-streaming/guides/acl-user-data#access-control-in-superfluid "Direct link to Access Control in Superfluid")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Access control is a crucial aspect of smart contract security, allowing certain addresses to perform specific actions. In the context of Superfluid and money streaming, Access Control Lists (ACLs) enables one address (the Flow Operator) to manage streams on behalf of another address.
### How Access Control Works in Superfluid[](https://docs.superfluid.org/docs/protocol/money-streaming/guides/acl-user-data#how-access-control-works-in-superfluid "Direct link to How Access Control Works in Superfluid")
Superfluid implements a flexible permission system for flow management:
1. **Granting Permissions**: An account can grant permissions to a flow operator, specifying what actions they can perform (create, update, delete flows) and setting a flow rate allowance.
2. **Flow Rate Allowance**: This is the maximum net flow rate that the operator can create on behalf of the account.
3. **Operator Actions**: Once granted permissions, the operator can perform the allowed actions within the specified flow rate allowance.
Access Control for [Distribution Pools](https://docs.superfluid.org/docs/protocol/distributions/overview)
In this document, we address Access Control for Money Streaming (CFA). Currently, there are no access control functions for [Distribution Pools](https://docs.superfluid.org/docs/protocol/distributions/overview)
. However, you can build your own access control system using the SuperTokenV1Library functions.
### Key Functions for Access Control[](https://docs.superfluid.org/docs/protocol/money-streaming/guides/acl-user-data#key-functions-for-access-control "Direct link to Key Functions for Access Control")
1. `setFlowPermissions`: Set specific permissions for a flow operator.
function setFlowPermissions( ISuperToken token, address flowOperator, bool allowCreate, bool allowUpdate, bool allowDelete, int96 flowRateAllowance) internal returns (bool)
2. `flowFrom`: Control a flow as an operator on behalf of another account.
function flowFrom( ISuperToken token, address sender, address receiver, int96 flowRate) internal returns (bool)
3. `revokeFlowPermissions`: Revoke all permissions from a flow operator.
function revokeFlowPermissions( ISuperToken token, address flowOperator) internal returns (bool)
Full list of functions
For a full list of functions related to access control, refer to the [SuperTokenV1Library technical reference](https://docs.superfluid.org/docs/technical-reference/SuperTokenV1Library)
.
User Data in Superfluid[](https://docs.superfluid.org/docs/protocol/money-streaming/guides/acl-user-data#user-data-in-superfluid "Direct link to User Data in Superfluid")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
User data in Superfluid allows developers to attach additional information to transactions. This can be used for various purposes, such as including metadata, triggering specific logic in receiver contracts, or implementing off-chain systems.
### How to Use User Data[](https://docs.superfluid.org/docs/protocol/money-streaming/guides/acl-user-data#how-to-use-user-data "Direct link to How to Use User Data")
Many functions in the SuperTokenV1Library accept a `userData` parameter. This is typically a `bytes` type, allowing you to encode any data you want to include.
Example of using user data when controlling a flow:
function flowFrom( ISuperToken token, address sender, address receiver, int96 flowRate, bytes memory userData) internal returns (bool)
You can encode various types of data into the `userData` parameter. For example:
bytes memory userData = abi.encode(uint256(1234), "Hello, Superfluid!");createFlowWithUserData(token, receiver, flowRate, userData);
Example: Granting Permissions and Creating a Flow[](https://docs.superfluid.org/docs/protocol/money-streaming/guides/acl-user-data#example-granting-permissions-and-creating-a-flow "Direct link to Example: Granting Permissions and Creating a Flow")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Here's a simple example demonstrating how one contract can grant permissions to another, allowing it to create a flow on its behalf:
// SPDX-License-Identifier: MITpragma solidity ^0.8.0;import { ISuperfluid, ISuperToken } from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol";import { SuperTokenV1Library } from "@superfluid-finance/ethereum-contracts/contracts/apps/SuperTokenV1Library.sol";contract PermissionGranter { using SuperTokenV1Library for ISuperToken; function grantPermissions( ISuperToken token, address operator, int96 flowRateAllowance ) external { token.setFlowPermissions( operator, true, // allowCreate false, // allowUpdate false, // allowDelete flowRateAllowance ); }}contract FlowCreator { using SuperTokenV1Library for ISuperToken; function createFlowAsOperator( ISuperToken token, address sender, address receiver, int96 flowRate ) external { token.flowFrom(sender, receiver, flowRate); }}
In this example, `PermissionGranter` can grant permissions to `FlowCreator`. Once permissions are granted, `FlowCreator` can create flows on behalf of the address that called `grantPermissions`.
To use these contracts:
1. Deploy both contracts.
2. Call `grantPermissions` on `PermissionGranter`, passing the token address, the address of the `FlowCreator` contract, and the desired flow rate allowance.
3. Now, anyone can call `createFlowAsOperator` on `FlowCreator`, which will create a flow from the address that granted permissions to the specified receiver.
This setup allows for flexible delegation of flow creation, which can be useful in various DeFi applications, automated systems, or multi-sig wallet scenarios.
* [Introduction to SuperTokenV1Library](https://docs.superfluid.org/docs/protocol/money-streaming/guides/acl-user-data#introduction-to-supertokenv1library)
* [Access Control in Superfluid](https://docs.superfluid.org/docs/protocol/money-streaming/guides/acl-user-data#access-control-in-superfluid)
* [How Access Control Works in Superfluid](https://docs.superfluid.org/docs/protocol/money-streaming/guides/acl-user-data#how-access-control-works-in-superfluid)
* [Key Functions for Access Control](https://docs.superfluid.org/docs/protocol/money-streaming/guides/acl-user-data#key-functions-for-access-control)
* [User Data in Superfluid](https://docs.superfluid.org/docs/protocol/money-streaming/guides/acl-user-data#user-data-in-superfluid)
* [How to Use User Data](https://docs.superfluid.org/docs/protocol/money-streaming/guides/acl-user-data#how-to-use-user-data)
* [Example: Granting Permissions and Creating a Flow](https://docs.superfluid.org/docs/protocol/money-streaming/guides/acl-user-data#example-granting-permissions-and-creating-a-flow)
---
# Create, Update, and Delete Flows | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#__docusaurus_skipToContent_fallback)
On this page
This guide covers various methods for managing flows in Superfluid from your client application side. This guide will not cover how to interact with the protocol from another smart contract. For that, please refer to the [Create, Update, and Delete Flows guide](https://docs.superfluid.org/docs/protocol/money-streaming/guides/create-update-delete-flow)
in the Contracts section.
Prerequisites[](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#prerequisites "Direct link to Prerequisites")
----------------------------------------------------------------------------------------------------------------------------------------------
Before proceeding, ensure you have:
* Familiarity with JavaScript (and an EVM framework such as ethers.js, viem or wagmi).
* Basic understanding of Superfluid and its functionalities.
* Access to a development environment for developing client applications.
What is a flow?[](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#what-is-a-flow "Direct link to What is a flow?")
---------------------------------------------------------------------------------------------------------------------------------------------------
In Superfluid terminology, a flow is a continuous stream of tokens from one account to another. It is a fundamental concept in the Superfluid protocol, enabling real-time, continuous payments between accounts.
What is the difference between a "Stream" and a "Flow"?
This is a small technicality which is not necessarily important to understand. However, in Superfluid, a "Flow" is a more general term than a "Stream". A Stream is a non-zero flow, while a zero flow is not considered a Stream.
How to interact with the Superfluid protocol from a client application?[](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#how-to-interact-with-the-superfluid-protocol-from-a-client-application "Direct link to How to interact with the Superfluid protocol from a client application?")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
There are mainly two ways to interact with the Superfluid protocol from a client application:
* The [`CFAv1Forwarder`](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder)
contract: This contract is used to create, update, and delete flows.
* The [`GDAv1Forwarder`](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder)
contract: This contract is used to create and manage Distribution Pools.
For the purposes of this guide, we will focus on the [`CFAv1Forwarder`](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder)
contract which allows you to create, update, and delete flows.
Where does the name CFAv1Forwarder come from?
The name `CFAv1Forwarder` is derived from the term "Constant Flow Agreement" (CFA) which is the underlying agreement that governs Money Streaming in Superfluid.
Interacting with the CFAv1Forwarder Contract[](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#interacting-with-the-cfav1forwarder-contract "Direct link to Interacting with the CFAv1Forwarder Contract")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
To interact with Money Streaming, you'll need to use the `CFAv1Forwarder` contract. Here's how to get started:
### Contract ABI and Address[](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#contract-abi-and-address "Direct link to Contract ABI and Address")
You can find the full ABI of the `CFAv1Forwarder` contract in the [CFAv1Forwarder technical reference](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder)
.
The `CFAv1Forwarder` contract address is the same on all networks:
0xcfA132E353cB4E398080B9700609bb008eceB125
### Initiating Contract Interaction with ethers.js[](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#initiating-contract-interaction-with-ethersjs "Direct link to Initiating Contract Interaction with ethers.js")
Here's an example of how to initiate interaction with the `CFAv1Forwarder` contract using ethers.js:
import { ethers } from 'ethers';// Assuming you have a provider set up (e.g., using MetaMask)const provider = new ethers.providers.Web3Provider(window.ethereum);// The address of the CFAv1Forwarder contractconst forwarderAddress = '0xcfA132E353cB4E398080B9700609bb008eceB125';// The ABI of the CFAv1Forwarder contract (import this from the technical reference)const forwarderABI = [...]; // Insert the ABI here// Create a contract instanceconst forwarderContract = new ethers.Contract(forwarderAddress, forwarderABI, provider.getSigner());
Now that we have our contract instance set up, let's look at how to create, update, and delete flows.
Creating a Flow[](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#creating-a-flow "Direct link to Creating a Flow")
----------------------------------------------------------------------------------------------------------------------------------------------------
To create a new flow, you can use the `createFlow` function of the `CFAv1Forwarder` contract.
### Function Signature[](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#function-signature "Direct link to Function Signature")
function createFlow( ISuperToken token, address sender, address receiver, int96 flowrate, bytes userData) external returns (bool)
### Parameters[](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#parameters "Direct link to Parameters")
* `token`: The address of the Super Token you want to stream.
* `sender`: The address that will be sending the tokens.
* `receiver`: The address that will be receiving the tokens.
* `flowrate`: The rate at which tokens will be streamed, in tokens per second (using 18 decimal places).
* `userData`: (Optional) Additional data to include with the transaction. Use "0x" if not needed.
### Example Usage[](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#example-usage "Direct link to Example Usage")
const createFlow = async (tokenAddress, receiver, flowRate) => { try { const tx = await forwarderContract.createFlow( tokenAddress, await provider.getSigner().getAddress(), // sender (current user) receiver, flowRate, "0x" // no user data ); await tx.wait(); console.log("Flow created successfully!"); } catch (error) { console.error("Error creating flow:", error); }};
using setFlowrate instead
You can also use the `setFlowrate` function to update the flow rate of an existing flow. For a full list of functions available in the `CFAv1Forwarder` contract, refer to the [CFAv1Forwarder technical reference](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder)
.
Updating a Flow[](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#updating-a-flow "Direct link to Updating a Flow")
----------------------------------------------------------------------------------------------------------------------------------------------------
To update an existing flow, use the `updateFlow` function.
### Function Signature[](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#function-signature-1 "Direct link to Function Signature")
function updateFlow( ISuperToken token, address sender, address receiver, int96 flowrate, bytes userData) external returns (bool)
### Parameters[](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#parameters-1 "Direct link to Parameters")
The parameters are the same as for `createFlow`. The `flowrate` parameter specifies the new flow rate.
### Example Usage[](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#example-usage-1 "Direct link to Example Usage")
const updateFlow = async (tokenAddress, receiver, newFlowRate) => { try { const tx = await forwarderContract.updateFlow( tokenAddress, await provider.getSigner().getAddress(), // sender (current user) receiver, newFlowRate, "0x" // no user data ); await tx.wait(); console.log("Flow updated successfully!"); } catch (error) { console.error("Error updating flow:", error); }};
using setFlowrate instead
You can also use the `setFlowrate` function to update the flow rate of an existing flow. For a full list of functions available in the `CFAv1Forwarder` contract, refer to the [CFAv1Forwarder technical reference](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder)
.
Deleting a Flow[](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#deleting-a-flow "Direct link to Deleting a Flow")
----------------------------------------------------------------------------------------------------------------------------------------------------
To stop and delete an existing flow, use the `deleteFlow` function.
### Function Signature[](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#function-signature-2 "Direct link to Function Signature")
function deleteFlow( ISuperToken token, address sender, address receiver, bytes userData) external returns (bool)
### Parameters[](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#parameters-2 "Direct link to Parameters")
* `token`: The address of the Super Token of the flow you want to delete.
* `sender`: The address that is sending the tokens in the flow.
* `receiver`: The address that is receiving the tokens in the flow.
* `userData`: (Optional) Additional data to include with the transaction. Use "0x" if not needed.
### Example Usage[](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#example-usage-2 "Direct link to Example Usage")
const deleteFlow = async (tokenAddress, receiver) => { try { const tx = await forwarderContract.deleteFlow( tokenAddress, await provider.getSigner().getAddress(), // sender (current user) receiver, "0x" // no user data ); await tx.wait(); console.log("Flow deleted successfully!"); } catch (error) { console.error("Error deleting flow:", error); }};
using setFlowrate instead
You can also use the `setFlowrate` function to update the flow rate of an existing flow. For a full list of functions available in the `CFAv1Forwarder` contract, refer to the [CFAv1Forwarder technical reference](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder)
.
Building a Simple UI[](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#building-a-simple-ui "Direct link to Building a Simple UI")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
Here's an example of how you might build a simple UI to interact with these functions:
Live Editor
function FlowManager() {
const \[tokenAddress, setTokenAddress\] \= useState(''); const \[receiver, setReceiver\] \= useState(''); const \[flowRate, setFlowRate\] \= useState(''); const \[walletConnected, setWalletConnected\] \= useState(false); const \[account, setAccount\] \= useState(''); const toast \= useToast();
const forwarderAddress \= '0xcfA132E353cB4E398080B9700609bb008eceB125'; const forwarderABI \= CFAv1ForwarderABI; // You will need to import the ABI in your code. You can do that from: https://docs.superfluid.finance/docs/technical-reference/CFAv1Forwarder
const connectWallet \= async () \=> { if (typeof window.ethereum !== 'undefined') { try { await window.ethereum.request({ method: 'eth\_requestAccounts' }); const provider \= new ethers.providers.Web3Provider(window.ethereum); const signer \= provider.getSigner(); const address \= await signer.getAddress(); setAccount(address); setWalletConnected(true); toast({ title: 'Wallet connected', description: \`Connected to ${address}\`, status: 'success', duration: 3000, isClosable: true, }); } catch (error) { console.error('Failed to connect wallet:', error); toast({ title: 'Connection failed', description: 'Failed to connect wallet. Please try again.', status: 'error', duration: 3000, isClosable: true, }); } } else { toast({ title: 'Metamask not detected', description: 'Please install Metamask to use this feature.', status: 'warning', duration: 3000, isClosable: true, }); } };
const handleFlow \= async (action) \=> { if (!walletConnected) { toast({ title: 'Wallet not connected', description: 'Please connect your wallet first.', status: 'warning', duration: 3000, isClosable: true, }); return; }
const provider \= new ethers.providers.Web3Provider(window.ethereum); const signer \= provider.getSigner(); const contract \= new ethers.Contract(forwarderAddress, forwarderABI, signer);
try { let tx; switch (action) { case 'create': tx \= await contract.createFlow(tokenAddress, account, receiver, flowRate, "0x"); break; case 'update': tx \= await contract.updateFlow(tokenAddress, account, receiver, flowRate, "0x"); break; case 'delete': tx \= await contract.deleteFlow(tokenAddress, account, receiver, "0x"); break; } await tx.wait(); toast({ title: 'Transaction successful', description: \`Flow ${action}d successfully!\`, status: 'success', duration: 3000, isClosable: true, }); } catch (error) { console.error(\`Error ${action}ing flow:\`, error); toast({ title: 'Transaction failed', description: \`Failed to ${action} flow. Please try again.\`, status: 'error', duration: 3000, isClosable: true, }); } };
return ( Flow Manager
{!walletConnected ? ( ) : ( Connected: {account} )}
setTokenAddress(e.target.value)} /> setReceiver(e.target.value)} /> setFlowRate(e.target.value)} />
);
}
Result
Loading...
This UI provides input fields for the token address, receiver address, and flow rate, along with buttons to create, update, and delete flows. You would need to implement the `createFlow`, `updateFlow`, and `deleteFlow` functions as shown in the previous examples.
the example does not work on your developer environment?
The example above is a live example and requires the ABI to be imported. In the case of this example, the ABI has already been imported through the live coder.
In order to make it work on your developer environment, head to the [CFAv1Forwarder technical reference](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder)
and copy the ABI. Then, replace the `forwarderABI` variable in the example with the ABI you copied.
* [Prerequisites](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#prerequisites)
* [What is a flow?](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#what-is-a-flow)
* [How to interact with the Superfluid protocol from a client application?](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#how-to-interact-with-the-superfluid-protocol-from-a-client-application)
* [Interacting with the CFAv1Forwarder Contract](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#interacting-with-the-cfav1forwarder-contract)
* [Contract ABI and Address](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#contract-abi-and-address)
* [Initiating Contract Interaction with ethers.js](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#initiating-contract-interaction-with-ethersjs)
* [Creating a Flow](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#creating-a-flow)
* [Function Signature](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#function-signature)
* [Parameters](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#parameters)
* [Example Usage](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#example-usage)
* [Updating a Flow](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#updating-a-flow)
* [Function Signature](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#function-signature-1)
* [Parameters](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#parameters-1)
* [Example Usage](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#example-usage-1)
* [Deleting a Flow](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#deleting-a-flow)
* [Function Signature](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#function-signature-2)
* [Parameters](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#parameters-2)
* [Example Usage](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#example-usage-2)
* [Building a Simple UI](https://docs.superfluid.org/docs/sdk/money-streaming/create-update-delete-flow#building-a-simple-ui)
---
# Liquidations & TOGA | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/protocol/advanced-topics/solvency/liquidations-and-toga#__docusaurus_skipToContent_fallback)
On this page
Liquidation and Solvency[](https://docs.superfluid.org/docs/protocol/advanced-topics/solvency/liquidations-and-toga#liquidation-and-solvency "Direct link to Liquidation and Solvency")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
When opening a stream, the protocol will take a small `buffer` or `deposit`. By leaving their streams open for too long, stream creators stand to lose this `buffer`. This mechanism creates the main incentive for users to close their Superfluid streams before running out of tokens. It is a user's own responsibility to close their stream.
`superApps` can also draw an `owedDeposit`, allowing them to open a stream of the same size, without needing an initial balance.
Here's the general flow of solvency states for Super Tokens in a Constant Flow Agreement (Money Streaming):
#### 1\. Solvent[](https://docs.superfluid.org/docs/protocol/advanced-topics/solvency/liquidations-and-toga#1-solvent "Direct link to 1. Solvent")
Everyone is in good standing. The sender's balance is greater than 0. The stream flows to the receiver as expected, and there are enough tokens to back the stream.
#### 2\. Critical[](https://docs.superfluid.org/docs/protocol/advanced-topics/solvency/liquidations-and-toga#2-critical "Direct link to 2. Critical")
The sender's balance is now zero, and the permissions on the stream now allow anyone to close it. Until the stream is actually closed, funds are paid to the receiver's wallet using the sender's initial `buffer`.
The critical period is subdivided into 2 sub-periods:
a) _**Patrician Period**_: starts when the stream becomes critical (duration defined as governance parameter)
b) _**Plebs Period**_: spans the remaining timeframe until the stream becomes insolvent
When the stream is closed, any remaining `buffer` is taken and assigned/distributed either to the _**PIC**_ or a _**Pleb**_.
If the stream is closed during the Plebs Period, we call the account closing the stream a Pleb.
#### 3\. Insolvent[](https://docs.superfluid.org/docs/protocol/advanced-topics/solvency/liquidations-and-toga#3-insolvent "Direct link to 3. Insolvent")
If the stream isn't closed, and the sender's deposit is completely consumed, then the insolvent period begins. The stream will continue to the receiver, however since these tokens don't actually exist in the sender's wallet, we must keep track of this `deficit` so that the Super Token itself can remain solvent within the Superfluid Protocol.
We also call this open ended timeframe the _**Pirate Period**_.
When the stream is eventually closed, the `deficit` is taken from the PICs stake as a slashing fee. This slashing fee is then burned, to offset the tokens created by the insolvent stream. Additionally, a reward equal in amount to the `buffer` amount before its consumption is issued to the account closing the stream, whom we call a _**Pirate.**_. This reward is also detracted from the PICs stake.

_Visualization showing the tota user balance as well as the outgoing stream part of the buffer_
### Patricians, Plebs and Pirates (3Ps)[](https://docs.superfluid.org/docs/protocol/advanced-topics/solvency/liquidations-and-toga#patricians-plebs-and-pirates-3ps "Direct link to Patricians, Plebs and Pirates (3Ps)")
Each token has an account called a _**PIC (Patrician in Charge)**_.
Every time a stream is closed while Critical during the Patrician Period, the remaining amount of the `buffer` balance of the closed stream is taken and added to the PICs stake as a reward.
Every time a stream is closed while Critical during the Plebs Period, the remaining buffer is rewarded to the Pleb.
Every time a stream is closed while Insolvent, the PIC is slashed, and the Pirate is rewarded with the full buffer amount.
The monopoly on rewards during the Patrician Period gives PICs an incentive to make sure streams are closed during that timeframe.
They can set up one or multiple redundant instances of the [superfluid-sentinel](https://github.com/superfluid-finance/superfluid-sentinel)
(and/or other mechanisms for closing streams) to ensure this. Note that the PIC account is not needed (not in a _hot wallet_) for this operations as the rewards incurred during the patrician period will be added to the PIC stake regardless of transaction sender.
Plebs act as a fallback in case PICs fail to do their job despite of the incentives.
The earlier in the Pleb Period a Pleb closes the stream, the more buffer there's left as a reward.
Unlike the PIC, individual Plebs and Pirates don't have a monopoly. Whoever manages to get a stream closing transaction included first during the Plebs / Pirate Period, gets the reward.
Patrician, Pleb and Pirate are roles which map to accounts in specific circumstances.
The same account could have any of those roles in the context of various stream closing transactions, defined by the timing of that transaction and the state of the TOGA contract (list of PICs) at the time of transaction execution. The reference sentinel implementation provides configuration options influencing that behaviour and timing of transactions.
Note that thanks to this flexible roles model, PICs have an incentive to close streams even after missing the Patrician Period:
1. they can still get rewards, essentially acting as a Pleb or Pirate in the context of that transaction
2. due to the slashing of the `deficit` from their stake, their incentive to close insolvent streams grows linearly over time
-75b0a4376c6d235d527e77078fac0b99.png)
### TOGA - Transparent OnGoing Auction[](https://docs.superfluid.org/docs/protocol/advanced-topics/solvency/liquidations-and-toga#toga---transparent-ongoing-auction "Direct link to TOGA - Transparent OnGoing Auction")
Since the role of a PIC comes with a monopoly on rewards incurred during the Patrician Period, a fair mechanism for assigning this role is needed. Such a mechanism is provided by the TOGA.
To become a PIC for a token, aspiring Patricians must post a `stake` to the TOGA contract, in the token they are trying to become a PIC for. If the new `stake` is higher than the existing `stake`, the new Patrician becomes the PIC, and the previous Patrician gets their current `stake` back.
PICs can't remove their `stake` at will through a single transaction, but rather, they have to specify an `exitRate`, which defines the flowrate of a Stream to their account. The `exitRate` is also not completely arbitrary, it is limited such that the `stake` will remain above zero for at least a week.
All liquidation rewards are added to the `stake`, thus - depending on the exitRate set by the PIC and the number of size of streams becoming critical - the stake of a PIC could shrink, grow or stay the same over time. (The maximum allowed `exitRate` is calculated based on the worst case of no rewards being added during that timeframe.)
In order to become the PIC, you can either use the Dapp at [https://toga.superfluid.finance/](https://toga.superfluid.finance/)
or use `ERC777.send()` to post the desired stake to the TOGA contract - optionally with an `exitRate` set in the `data` parameter if you don't like the default `exitRate`. The TOGA contract implements an ERC777 callback for the auction mechanism.
CAUTION
Do NOT use `ERC20.transfer()` for TOGA bids, because those may not trigger the needed callback in the future.
### Current Parameters[](https://docs.superfluid.org/docs/protocol/advanced-topics/solvency/liquidations-and-toga#current-parameters "Direct link to Current Parameters")
* Polygon
* Ethereum Mainnet
* Gnosis Chain
* Optimism
* Arbitrum
* Goerli
**Deposit**
4 hour `deposit`
4 hour maximum `owedDeposit`
30 minutes `patrician period`
**TOGA**
1 week minimum `exitPeriod`
4 week default `exitPeriod`
**Minimum Deposit**
Ethereum L1 is a different environment from other networks where Superfluid has been deployed. This is due to the fact that performing any operation on L1 is much more expensive in terms of gas cost than it is on other networks.
To cover additional costs incurred by sentinels, tokens on L1 have been deployed with minimum deposit values. This means that the buffer on each of these tokens will not always be calculated as 4 hours worth of the stream as it is on lower cost networks.
* ETHx: 0.042 ETHx
* USDCx & DAIx: 69 tokens
**Deposit**
4 hour `deposit` (note that this value only applies if the deposit is > the min deposit)
4 hour maximum `owedDeposit`
30 minutes `patrician period`
**TOGA**
1 week minimum `exitPeriod`
4 week default `exitPeriod`
**Deposit**
4 hour `deposit`
4 hour maximum `owedDeposit`
30 minutes `patrician period`
**TOGA**
1 week minimum `exitPeriod`
4 week default `exitPeriod`
**Deposit**
4 hour `deposit`
4 hour maximum `owedDeposit`
30 minutes `patrician period`
**TOGA**
1 week minimum `exitPeriod`
4 week default `exitPeriod`
**Deposit**
4 hour `deposit`
4 hour maximum `owedDeposit`
30 minutes `patrician period`
**TOGA**
1 week minimum `exitPeriod`
4 week default `exitPeriod`
**Deposit**
1 hour `deposit`
1 hour maximum `owedDeposit`
12 minutes `patrician period`
**TOGA**
1 week minimum `exitPeriod`
4 week default `exitPeriod`
* * *
info
Note that this parameter definitions in terms of time units refer to simplified idealized scenarios and are basically lower bounds.
The deposit related timeframes directly apply for streams where the sender account has no incoming streams and where the net flowrate is thus equal to the outgoing flowrate. If however the sender account has incoming streams, this timeframes are stretched proportionally. If for example the aggregate incoming flowrate is half of the aggregate outgoing flowrate, the time for the buffer to be consumed (critial period) doubles, as do the patrician period and the plebs period. If the aggregate incoming flowrate equals the aggregate outgoing flowrate (net flowrate = zero), those periods become potentially infinite (as long as the net flowrate doesn't change), because in that case the buffer wouldn't be consumed further, but not restored either, leaving outgoing streams critical in perpetuity.
For the TOGA `exitPeriod`, something similar applies - it's the lower bound for how long it would take a PIC to stream out the stake with a given `exitRate`, assuming nothing is added to the stake during that time. In practice, accrued liquidation rewards may be added to the stake during that time, leading to a proportional extension of the exitPeriod. In theory such added rewards could even completely offset the exitRate, leading to a net growing stake. In that case the PIC could periodically increase the exitRate (a larger stake allows for a larger exitRate) and would eventually be able to set an exitRate which leads to a shrinking stake.
* [Liquidation and Solvency](https://docs.superfluid.org/docs/protocol/advanced-topics/solvency/liquidations-and-toga#liquidation-and-solvency)
* [Patricians, Plebs and Pirates (3Ps)](https://docs.superfluid.org/docs/protocol/advanced-topics/solvency/liquidations-and-toga#patricians-plebs-and-pirates-3ps)
* [TOGA - Transparent OnGoing Auction](https://docs.superfluid.org/docs/protocol/advanced-topics/solvency/liquidations-and-toga#toga---transparent-ongoing-auction)
* [Current Parameters](https://docs.superfluid.org/docs/protocol/advanced-topics/solvency/liquidations-and-toga#current-parameters)
---
# Running a Sentinel | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/protocol/advanced-topics/solvency/running-a-sentinnel#__docusaurus_skipToContent_fallback)
On this page
In our section on [Liquidations & TOGA](https://docs.superfluid.org/docs/protocol/advanced-topics/solvency/liquidations-and-toga)
, we described how the Superfluid protocol handles solvency & liquidations. Sentinels play a vital role in this process. This page provides links to various resources that will aid you on your journey to help secure the protocol 🛡⚔️
### Who Should Run a Sentinel?[](https://docs.superfluid.org/docs/protocol/advanced-topics/solvency/running-a-sentinnel#who-should-run-a-sentinel "Direct link to Who Should Run a Sentinel?")
1. Crypto enthusiasts who want to help secure a new, innovative primitive for web3 😁
2. Teams that have a service running on Superfluid. Perhaps you’ve launched your own dapp or your own Super Token, and you want to be 100% certain that your users are in good standing.
3. Professional operators who want to run profitable enterprises. If you have DevOps skills and/or you’re able to acquire capital to become the PIC for several tokens, participating in this process could be a good opportunity!
Getting Started[](https://docs.superfluid.org/docs/protocol/advanced-topics/solvency/running-a-sentinnel#getting-started "Direct link to Getting Started")
------------------------------------------------------------------------------------------------------------------------------------------------------------
### Running a Sentinel - Step By Step Guide[](https://docs.superfluid.org/docs/protocol/advanced-topics/solvency/running-a-sentinnel#running-a-sentinel---step-by-step-guide "Direct link to Running a Sentinel - Step By Step Guide")
### Sentinel Repository[](https://docs.superfluid.org/docs/protocol/advanced-topics/solvency/running-a-sentinnel#sentinel-repository "Direct link to Sentinel Repository")
If you want to start running a Sentinel today, you can clone [this repo](https://github.com/superfluid-finance/superfluid-sentinel)
and customize your own `.env` file before starting the software. At minimum, you're going to need a reliable RPC URL, and a private key with native tokens to pay for gas when performing liquidations. Detailed instructions for running your Sentinel can be found in the repository's README and in the above video.
[](https://github.com/superfluid-finance/superfluid-sentinel)
### Becoming the PIC[](https://docs.superfluid.org/docs/protocol/advanced-topics/solvency/running-a-sentinnel#becoming-the-pic "Direct link to Becoming the PIC")
You can become the PIC by connecting your wallet at the [TOGA dashboard.](https://toga.superfluid.finance/)
There, you'll also see information on the current PIC stake amount, stream data by token, and a real time list of all liquidations. TOGA contract addresses are also available in our [Explorer](https://explorer.superfluid.finance/)
for each network.
[The TOGA Dashboard](https://toga.superfluid.finance/)
### Additional Resources[](https://docs.superfluid.org/docs/protocol/advanced-topics/solvency/running-a-sentinnel#additional-resources "Direct link to Additional Resources")
Running sentinels does require some active management.
We recommend you to join our discord server, and specifically the sentinels channel to keep in touch with any news and updates!
[](http://discord.superfluid.finance/)
Glossary of Terms:[](https://docs.superfluid.org/docs/protocol/advanced-topics/solvency/running-a-sentinnel#glossary-of-terms "Direct link to Glossary of Terms:")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
**Buffer**: The amount of tokens that an account must temporarily lock up when a stream is started.
**Liquidation**: Occurs when a stream is closed by a sentinel once an account's token balance hits zero while still streaming funds
**Sentinel**: A node that watches the Superfluid network & closes streams when they become critical or insolvent. Anyone can become a Sentinel by running a node
**PIC**: The Patrician in Charge who receives rewards each time a stream is closed in the priority period when an account goes critical
**TOGA**: the Transparent Ongoing Auction which allows anyone to become the Patrician in Charge (PIC) if they put up a higher staked amount than the previous PIC
**Stake**: The amount of funds locked in the TOGA contract by the Patrician in Charge (PIC)
* [Who Should Run a Sentinel?](https://docs.superfluid.org/docs/protocol/advanced-topics/solvency/running-a-sentinnel#who-should-run-a-sentinel)
* [Getting Started](https://docs.superfluid.org/docs/protocol/advanced-topics/solvency/running-a-sentinnel#getting-started)
* [Running a Sentinel - Step By Step Guide](https://docs.superfluid.org/docs/protocol/advanced-topics/solvency/running-a-sentinnel#running-a-sentinel---step-by-step-guide)
* [Sentinel Repository](https://docs.superfluid.org/docs/protocol/advanced-topics/solvency/running-a-sentinnel#sentinel-repository)
* [Becoming the PIC](https://docs.superfluid.org/docs/protocol/advanced-topics/solvency/running-a-sentinnel#becoming-the-pic)
* [Additional Resources](https://docs.superfluid.org/docs/protocol/advanced-topics/solvency/running-a-sentinnel#additional-resources)
* [Glossary of Terms:](https://docs.superfluid.org/docs/protocol/advanced-topics/solvency/running-a-sentinnel#glossary-of-terms)
---
# Token-Cost-Averaging | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/concepts/use-cases/defi#__docusaurus_skipToContent_fallback)
On this page
Token-Cost-Averaging\* (TCA) is one possible application designed to leverage the power of Superfluid streams. This application could allow the user to swap tokens in continuous real-time streams: stream in your Sell token and receive back the Buy token periodically.
What is Token-Cost-Averaging (TCA)?[](https://docs.superfluid.org/docs/concepts/use-cases/defi#what-is-token-cost-averaging-tca "Direct link to What is Token-Cost-Averaging (TCA)?")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Token-Cost-Averaging (TCA) is an investment strategy where an investor divides up the total amount to be invested across periodic purchases of a target asset (just like Dollar-Cost-Averaging but it's asset agnostic). This strategy gives users the best results over time by swapping tokens in continuous real-time streams: stream in your Sell token and receive back the Buy token periodically.
How does it work?[](https://docs.superfluid.org/docs/concepts/use-cases/defi#how-does-it-work "Direct link to How does it work?")
-----------------------------------------------------------------------------------------------------------------------------------
This application could be a new trading app powered by Superfluid. It could be designed to provide a more efficient and accessible way to perform Token-Cost-Averaging (TCA) by leveraging the power of Superfluid's streaming technology. Under the hood, the app would perform swaps time-continuously using a Time-Weighted Average Price (TWAP) oracle for liquidity source aggregation and a fair price over time.
The Superfluid Advantage[](https://docs.superfluid.org/docs/concepts/use-cases/defi#the-superfluid-advantage "Direct link to The Superfluid Advantage")
---------------------------------------------------------------------------------------------------------------------------------------------------------
Compared to existing TCA or DCA (Dollar-Cost-Averaging) dApps built on other protocols, Superfluid offers several advantages:
* **Efficiency and Accessibility:** Building on Money Streams makes TCA more efficient and accessible. By using Superfluid's streaming technology, it allows for continuous and automated investment flows, reducing the need for manual intervention and making investment more seamless and user-friendly.
* **Reduced Volatility Impact:** The core idea of TCA is to mitigate the risks associated with volatile market conditions. Superfluid enhances this approach by allowing for more frequent and smaller investments, thereby further reducing the potential impact of sudden market changes.
* **Innovation in DeFi:** By leveraging Superfluid's groundbreaking streaming technology, this TCA app stands at the forefront of innovation in decentralized finance, offering a unique approach to cryptocurrency investments.
* [What is Token-Cost-Averaging (TCA)?](https://docs.superfluid.org/docs/concepts/use-cases/defi#what-is-token-cost-averaging-tca)
* [How does it work?](https://docs.superfluid.org/docs/concepts/use-cases/defi#how-does-it-work)
* [The Superfluid Advantage](https://docs.superfluid.org/docs/concepts/use-cases/defi#the-superfluid-advantage)
---
# Super Apps | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/concepts/advanced-topics/super-apps#__docusaurus_skipToContent_fallback)
On this page
Super Apps represents a class of smart contracts that interact seamlessly with the Superfluid Protocol, enabling dynamic responses to Money streaming or Distributions (Also called Super Agreements).
Definition[](https://docs.superfluid.org/docs/concepts/advanced-topics/super-apps#definition "Direct link to Definition")
---------------------------------------------------------------------------------------------------------------------------
Super Apps are smart contracts registered with the Superfluid Protocol, designed to **react to Super Agreements**. These reactions are facilitated through callbacks, allowing Super Apps to engage dynamically with the creation, modification, and termination of Super Agreements.
**Reacting to Super Agreements**[](https://docs.superfluid.org/docs/concepts/advanced-topics/super-apps#reacting-to-super-agreements "Direct link to reacting-to-super-agreements")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
The reactivity of Super Apps stems from **callbacks**. These are segments of code within the Super App that are triggered when a Super Agreement involving the Super App is created, updated, or deleted. Such callbacks can execute various actions, from minting NFTs to initiating new Streams (Constant Flow Agreements).
### **Example - Stream Consolidator Super App**[](https://docs.superfluid.org/docs/concepts/advanced-topics/super-apps#example---stream-consolidator-super-app "Direct link to example---stream-consolidator-super-app")
Consider a Super App designed to consolidate all incoming flows into a single outgoing flow to a specific account (Account Z):
1. **Incoming Flow from Account A**: Account A initiates a Money Stream to the Super App (100 USDCx/mo). The Super App, in turn, starts an outbound Stream of the same rate to Account Z.
2. **Multiple Flow Adjustments**: If Account B starts a new Money Stream to the Super App (25 USDCx/mo) and Account A adjusts its flow (to 50 USDCx/mo), the Super App responds by updating its outbound Streams accordingly.
3. **Ongoing Reactions**: The Super App continues to adapt to new Money Streams or adjustments from various accounts, maintaining a reactive outbound flow.
info
**NOTE**: For a smart contract to qualify as a Super App, it must have defined callbacks to interact with Super Agreements.
Registering With The Protocol[](https://docs.superfluid.org/docs/concepts/advanced-topics/super-apps#registering-with-the-protocol "Direct link to Registering With The Protocol")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Registration of a Super App with the Superfluid Protocol is crucial. This registration process involves coding the smart contract to be identifiable as a Super App within the protocol.
### Purpose of Registration[](https://docs.superfluid.org/docs/concepts/advanced-topics/super-apps#purpose-of-registration "Direct link to Purpose of Registration")
* **Protocol Recognition**: When a stream is initiated towards a contract, the Superfluid Protocol checks if the recipient is a registered Super App.
* **Callback Activation**: If identified as a Super App, the protocol activates the Super App's callbacks, enabling its reactive capabilities.
-bf5f199ba30cb13d44e7ca74675b2ee2.png)
_Super App Registration_
Why Are Super Apps Needed?[](https://docs.superfluid.org/docs/concepts/advanced-topics/super-apps#why-are-super-apps-needed "Direct link to Why Are Super Apps Needed?")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Super Apps introduce a layer of programmability to Super Agreements, enhancing the potential for innovative decentralized applications (dApps).
### Potential Use Cases[](https://docs.superfluid.org/docs/concepts/advanced-topics/super-apps#potential-use-cases "Direct link to Potential Use Cases")
* **Lending Applications**: Automate loan repayments through Streams, eliminating the need for manual transactions.
* **Subscription Services**: Enable on-chain subscriptions paid via Streams, incorporating features like automatic affiliate payouts.
Super Apps open up a realm of possibilities, combining custom logic with the functionalities of Super Agreements to craft unique and scalable dApps.
For further inspiration, explore the following examples of Super Apps:
[Explore Super App Examples](https://github.com/superfluid-finance/super-examples)
* [Definition](https://docs.superfluid.org/docs/concepts/advanced-topics/super-apps#definition)
* [**Reacting to Super Agreements**](https://docs.superfluid.org/docs/concepts/advanced-topics/super-apps#reacting-to-super-agreements)
* [**Example - Stream Consolidator Super App**](https://docs.superfluid.org/docs/concepts/advanced-topics/super-apps#example---stream-consolidator-super-app)
* [Registering With The Protocol](https://docs.superfluid.org/docs/concepts/advanced-topics/super-apps#registering-with-the-protocol)
* [Purpose of Registration](https://docs.superfluid.org/docs/concepts/advanced-topics/super-apps#purpose-of-registration)
* [Why Are Super Apps Needed?](https://docs.superfluid.org/docs/concepts/advanced-topics/super-apps#why-are-super-apps-needed)
* [Potential Use Cases](https://docs.superfluid.org/docs/concepts/advanced-topics/super-apps#potential-use-cases)
---
# Social & Community | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/concepts/use-cases/social-and-community#__docusaurus_skipToContent_fallback)
On this page
Superfluid Protocol introduces innovative methods for community engagement and social token incentives, fostering long-term loyalty and participation.
Gradual Social Token Incentives[](https://docs.superfluid.org/docs/concepts/use-cases/social-and-community#gradual-social-token-incentives "Direct link to Gradual Social Token Incentives")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Rather than distributing social tokens in a single airdrop, Superfluid enables a gradual, by-the-second streaming of tokens to community members or creator audiences.
### Concept[](https://docs.superfluid.org/docs/concepts/use-cases/social-and-community#concept "Direct link to Concept")
* **Long-Term Engagement**: This model rewards ongoing loyalty and engagement, as opposed to immediate lump-sum airdrops.
* **Example**: Consider the scenario where the longer an individual holds a community NFT, the more social tokens they accrue, discouraging immediate selling post-airdrop.
Explore this concept with the [Reverb project](https://ethglobal.com/showcase/reverb-x2kgs)
, a platform that streams social tokens based on music listening habits.
Perpetual Conditional Rewards (PCR)[](https://docs.superfluid.org/docs/concepts/use-cases/social-and-community#perpetual-conditional-rewards-pcr "Direct link to Perpetual Conditional Rewards (PCR)")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
The PCR model within the Superfluid Protocol offers a scalable way to incentivize community actions based on specific Key Performance Indicators (KPIs).
### Mechanism[](https://docs.superfluid.org/docs/concepts/use-cases/social-and-community#mechanism "Direct link to Mechanism")
* **Reward Distribution**: Rewards are streamed to participants based on progress towards a KPI metric.
* **Funding and Execution**: Funded through money streams and distributed using the Superfluid Instant Distribution Agreement, with KPI verification via UMA's KPI Options.
-d7078ddafeeee6e5cfb7b458919f911d.png)
_Perpetual Conditional Rewards_
### Use Cases[](https://docs.superfluid.org/docs/concepts/use-cases/social-and-community#use-cases "Direct link to Use Cases")
* **Community Incentives**: Communities can incentivize members for activities like increasing Twitter followers or GitHub repo stars.
* **Scalable Incentives**: This system provides a method to reward members proportionally for contributing to communal goals.
For a deeper dive into the PCR concept, refer to this [Twitter thread by UMAprotocol](https://twitter.com/UMAprotocol/status/1517165913706930176?s=20&t=aWpKxDP7mqoQFGK9vcCygg)
.
Superfluid's approach to social tokens and community incentives represents a shift towards more dynamic and engagement-focused reward systems in the digital space.
* [Gradual Social Token Incentives](https://docs.superfluid.org/docs/concepts/use-cases/social-and-community#gradual-social-token-incentives)
* [Concept](https://docs.superfluid.org/docs/concepts/use-cases/social-and-community#concept)
* [Perpetual Conditional Rewards (PCR)](https://docs.superfluid.org/docs/concepts/use-cases/social-and-community#perpetual-conditional-rewards-pcr)
* [Mechanism](https://docs.superfluid.org/docs/concepts/use-cases/social-and-community#mechanism)
* [Use Cases](https://docs.superfluid.org/docs/concepts/use-cases/social-and-community#use-cases)
---
# Superfluid Host | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/concepts/advanced-topics/superfluid-host#__docusaurus_skipToContent_fallback)
On this page
The Superfluid Host Contract is a central element of the Superfluid Protocol, acting as a hub connecting Super Tokens, Super Agreements, and Super Apps.
_(1)-c445e0ae775f9000fb04b40cd9c63a94.png)
_Superfluid Host Contract_
Let's explore how the Host Contract interacts with different components of the Superfluid Protocol.
Super Agreements 🔗 Host Contract[](https://docs.superfluid.org/docs/concepts/advanced-topics/superfluid-host#super-agreements--host-contract "Direct link to Super Agreements 🔗 Host Contract")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Super Agreements, each with their unique contracts, interface with the Host Contract. Interaction with a Super Agreement is typically done by calling [`callAgreement()`](https://docs.superfluid.finance/superfluid/developers/solidity-examples/interacting-with-superfluid-smart-contracts)
on the Host Contract, specifying the agreement and parameters.
### Key Points[](https://docs.superfluid.org/docs/concepts/advanced-topics/superfluid-host#key-points "Direct link to Key Points")
* **Upgradeability and Expansion**: Super Agreements can be updated or new ones can be added and registered with the Host Contract.
info
**NOTE**: Direct interactions with Super Token contracts are not required for invoking Super Agreements. Instead, these agreements are accessed via the Host Contract, which then manages the Super Token balances involved.
Super Tokens 🔗 Host Contract[](https://docs.superfluid.org/docs/concepts/advanced-topics/superfluid-host#super-tokens--host-contract "Direct link to Super Tokens 🔗 Host Contract")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Super Tokens form the foundational layer of the Superfluid Protocol, where all Super Agreement data for an account is compiled.
### Functionality[](https://docs.superfluid.org/docs/concepts/advanced-topics/superfluid-host#functionality "Direct link to Functionality")
* **Aggregated Balance Calculation**: The impact of each Super Agreement on an account's balance is cumulatively calculated to determine the Super Token balance.
* **Data Sourcing**: Super Token contracts obtain necessary data through the Host Contract by iterating over the registered Super Agreements.
Super Apps 🔗 Host Contract[](https://docs.superfluid.org/docs/concepts/advanced-topics/superfluid-host#super-apps--host-contract "Direct link to Super Apps 🔗 Host Contract")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Registration of Super Apps with the Superfluid Host is essential to enable their callback functionalities.
### Interaction Mechanics[](https://docs.superfluid.org/docs/concepts/advanced-topics/superfluid-host#interaction-mechanics "Direct link to Interaction Mechanics")
* **Registration Requirement**: Super Apps must be registered with the Host to function correctly.
* **Callback Activation**: When a Super Agreement is engaged with a Super App, the Host Contract triggers the Super App's callbacks.
-cf6b7bba9bac1bb211064d9eb59c9287.png)
_Super Apps and Host Contract_
In summary, the Superfluid Host Contract is integral to the Superfluid Protocol, facilitating seamless interactions and integrations among Super Tokens, Super Agreements, and Super Apps.
* [Super Agreements 🔗 Host Contract](https://docs.superfluid.org/docs/concepts/advanced-topics/superfluid-host#super-agreements--host-contract)
* [Key Points](https://docs.superfluid.org/docs/concepts/advanced-topics/superfluid-host#key-points)
* [Super Tokens 🔗 Host Contract](https://docs.superfluid.org/docs/concepts/advanced-topics/superfluid-host#super-tokens--host-contract)
* [Functionality](https://docs.superfluid.org/docs/concepts/advanced-topics/superfluid-host#functionality)
* [Super Apps 🔗 Host Contract](https://docs.superfluid.org/docs/concepts/advanced-topics/superfluid-host#super-apps--host-contract)
* [Interaction Mechanics](https://docs.superfluid.org/docs/concepts/advanced-topics/superfluid-host#interaction-mechanics)
---
# Wrap and Unwrap Super Tokens | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/sdk/super-tokens/wrap-unwrap#__docusaurus_skipToContent_fallback)
On this page
This guide explains how to wrap and unwrap [Wrapped Super Tokens](https://docs.superfluid.org/docs/protocol/super-tokens/overview#types-of-super-tokens)
from your client application.
For all Wrapped Super Tokens, this is an important step in the user journey. It allows users to convert their ERC20 tokens to Super Tokens and vice versa.
how to deploy a wrapped super token?
If you need to deploy a Wrapped Super Token, you can follow our guide on [Deploying a Wrapped Super Token](https://docs.superfluid.org/docs/protocol/super-tokens/guides/deploy-super-token/deploy-wrapped-super-token)
.
Why do we need to wrap and unwrap Super Tokens?[](https://docs.superfluid.org/docs/sdk/super-tokens/wrap-unwrap#why-do-we-need-to-wrap-and-unwrap-super-tokens "Direct link to Why do we need to wrap and unwrap Super Tokens?")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Super Tokens are an enhanced version of ERC20 tokens, typically built on top of existing ERC20 tokens. This means that to use a Super Token, you often need to "wrap" an ERC20 token into its Super Token equivalent, and vice versa when you want to convert back to the original ERC20.
To find out the address of the underlying ERC20 token for a Super Token, you can use the `getUnderlyingToken` view function provided by the [Super Token interface contract](https://github.com/superfluid-finance/protocol-monorepo/blob/dev/packages/ethereum-contracts/contracts/interfaces/superfluid/ISuperToken.sol)
.
Super Token Interface
You can find the complete Super Token interface in our [ISuperToken Technical Reference](https://docs.superfluid.org/docs/technical-reference/ISuperToken)
.
Not all Wrapped Super Tokens have an underlying ERC20 token
In the case of [Native Super Tokens](https://docs.superfluid.org/docs/protocol/super-tokens/overview#3-native-super-tokens)
(like the ETHx), they do not have a underlying ERC20 token, but rather the native coin of the chain. Native Super Tokens inherit the ISETH interface, which you can also find in the [Technical Reference Section](https://docs.superfluid.org/docs/technical-reference/ISETH)
.
Super Token ABI[](https://docs.superfluid.org/docs/sdk/super-tokens/wrap-unwrap#super-token-abi "Direct link to Super Token ABI")
-----------------------------------------------------------------------------------------------------------------------------------
You can find the ABI for the Super Token Interface at the [ISuperToken Technical Reference](https://docs.superfluid.org/docs/technical-reference/ISuperToken)
. This ABI includes all the functions available for interacting with Super Tokens.
You can find the ABI for the Native Super Token Interface at the [ISETH Technical Reference](https://docs.superfluid.org/docs/technical-reference/ISETH)
. This ABI includes all the functions available for interacting with Native Super Tokens.
Wrapping and Unwrapping Functions[](https://docs.superfluid.org/docs/sdk/super-tokens/wrap-unwrap#wrapping-and-unwrapping-functions "Direct link to Wrapping and Unwrapping Functions")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Super Tokens provide several functions for wrapping (upgrading) and unwrapping (downgrading) tokens:
### Wrapping (Upgrading) Functions[](https://docs.superfluid.org/docs/sdk/super-tokens/wrap-unwrap#wrapping-upgrading-functions "Direct link to Wrapping (Upgrading) Functions")
For wrapping ERC20 tokens into Super Tokens, you can use the following functions from the [Super Token interface](https://docs.superfluid.org/docs/technical-reference/ISuperToken)
:
1. `upgrade(uint256 amount)`: Upgrades ERC20 tokens to Super Tokens.
2. `upgradeTo(address to, uint256 amount, bytes userData)`: Upgrades ERC20 tokens to Super Tokens and transfers them to a specified address.
For wrapping Native Super Tokens (like ETHx), you can use the following function from the [ISETH interface](https://docs.superfluid.org/docs/technical-reference/ISETH)
:
1. `upgradeByETH() payable`: Upgrades native tokens to Super Tokens.
2. `upgradeByETHTo(address to) payable`: Upgrades native tokens to Super Tokens and transfers them to a specified address.
### Unwrapping (Downgrading) Functions[](https://docs.superfluid.org/docs/sdk/super-tokens/wrap-unwrap#unwrapping-downgrading-functions "Direct link to Unwrapping (Downgrading) Functions")
For unwrapping Super Tokens back to ERC20 tokens, you can use the following functions from the [Super Token interface](https://docs.superfluid.org/docs/technical-reference/ISuperToken)
:
1. `downgrade(uint256 amount)`: Downgrades Super Tokens back to ERC20 tokens.
2. `downgradeTo(address to, uint256 amount)`: Downgrades Super Tokens to ERC20 tokens and transfers them to a specified address.
For unwrapping Native Super Tokens (like ETHx), you can use the following function from the [ISETH interface](https://docs.superfluid.org/docs/technical-reference/ISETH)
:
1. `downgradeToETH(uint256 amount)`: Downgrades Super Tokens back to native tokens.
Approval for Wrapping
Before wrapping ERC20 tokens into Super Tokens, you need to approve the Super Token contract to spend your ERC20 tokens. This is not needed for unwrapping.
Live Code Example: Wrapping ERC20 to Super Token[](https://docs.superfluid.org/docs/sdk/super-tokens/wrap-unwrap#live-code-example-wrapping-erc20-to-super-token "Direct link to Live Code Example: Wrapping ERC20 to Super Token")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Here's a simple example of how to wrap an ERC20 token into a Super Token using ethers.js:
Live Editor
function WrapERC20ToSuperToken() {
const \[amount, setAmount\] \= useState(''); const \[status, setStatus\] \= useState('');
const wrapTokens \= async () \=> { if (typeof window.ethereum !== 'undefined') { try { await window.ethereum.request({ method: 'eth\_requestAccounts' }); const provider \= new ethers.providers.Web3Provider(window.ethereum); const signer \= provider.getSigner();
// ERC20 token contract - you need to replace this with the actual token address const erc20Address \= '0x123...'; // Replace with actual ERC20 token address const erc20Abi \= \['function approve(address spender, uint256 amount) public returns (bool)'\]; const erc20Contract \= new ethers.Contract(erc20Address, erc20Abi, signer);
// Super Token contract - you need to replace this with the actual Super Token address const superTokenAddress \= '0x456...'; // Replace with actual Super Token address const superTokenAbi \= \['function upgrade(uint256 amount) external'\]; const superTokenContract \= new ethers.Contract(superTokenAddress, superTokenAbi, signer);
// Approve the Super Token contract to spend ERC20 tokens const approveTx \= await erc20Contract.approve(superTokenAddress, amount); await approveTx.wait(); setStatus('Approval successful. Wrapping tokens...');
// Upgrade (wrap) ERC20 to Super Token const upgradeTx \= await superTokenContract.upgrade(amount); await upgradeTx.wait(); setStatus('Tokens successfully wrapped!'); } catch (error) { console.error('Error:', error); setStatus('Error: ' + error.message); } } else { setStatus('Please install MetaMask!'); } };
return (
setAmount(e.target.value)} placeholder\="Amount to wrap" />
{status}
);
}
Result
Loading...
Replace Placeholder Addresses
Replace the placeholder addresses in the code above with actual contract addresses of your ERC20 token and Super Token.
This example demonstrates how to:
1. Connect to the user's wallet
2. Approve the Super Token contract to spend ERC20 tokens
3. Upgrade (wrap) ERC20 tokens to Super Tokens
For more detailed information about the ISuperToken interface and its functions, please refer to our [ISuperToken Technical Reference](https://docs.superfluid.org/docs/technical-reference/ISuperToken)
.
* [Why do we need to wrap and unwrap Super Tokens?](https://docs.superfluid.org/docs/sdk/super-tokens/wrap-unwrap#why-do-we-need-to-wrap-and-unwrap-super-tokens)
* [Super Token ABI](https://docs.superfluid.org/docs/sdk/super-tokens/wrap-unwrap#super-token-abi)
* [Wrapping and Unwrapping Functions](https://docs.superfluid.org/docs/sdk/super-tokens/wrap-unwrap#wrapping-and-unwrapping-functions)
* [Wrapping (Upgrading) Functions](https://docs.superfluid.org/docs/sdk/super-tokens/wrap-unwrap#wrapping-upgrading-functions)
* [Unwrapping (Downgrading) Functions](https://docs.superfluid.org/docs/sdk/super-tokens/wrap-unwrap#unwrapping-downgrading-functions)
* [Live Code Example: Wrapping ERC20 to Super Token](https://docs.superfluid.org/docs/sdk/super-tokens/wrap-unwrap#live-code-example-wrapping-erc20-to-super-token)
---
# Tracking Super Token Balances | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/sdk/super-tokens/super-token-balances#__docusaurus_skipToContent_fallback)
On this page
Super Token balances can dynamically change every second, presenting unique challenges and considerations for tracking them within the Ethereum ecosystem.
Compatibility with ERC20[](https://docs.superfluid.org/docs/sdk/super-tokens/super-token-balances#compatibility-with-erc20 "Direct link to Compatibility with ERC20")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
Super Tokens, while being ERC20 compatible, have some nuances in terms of forward compatibility with Ethereum infrastructure and tools.
### Key Points[](https://docs.superfluid.org/docs/sdk/super-tokens/super-token-balances#key-points "Direct link to Key Points")
* **Backward Compatibility**: Super Tokens work with existing Ethereum tools like Metamask and Gnosis Safe. You can view balances in Metamask, transfer funds using Gnosis Safe, and even swap Super Tokens on platforms like Uniswap.
* **Forward Compatibility**: While tools like Metamask and Gnosis Safe can display balances accurately, they do not support all functionalities of Super Tokens. For example, you cannot swap your streamed money on Automated Market Makers (eg. Uniswap).
Balance Tracking Considerations[](https://docs.superfluid.org/docs/sdk/super-tokens/super-token-balances#balance-tracking-considerations "Direct link to Balance Tracking Considerations")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Tracking the balance of Super Tokens requires a more nuanced approach than traditional ERC20 tokens.
### Challenges[](https://docs.superfluid.org/docs/sdk/super-tokens/super-token-balances#challenges "Direct link to Challenges")
* **Event-Based Tracking Limitation**: Some applications, like Etherscan, use `transfer` events to track user balances. However, due to scalability concerns, Super Tokens don't emit `transfer` events with every balance change, leading to potential discrepancies in displayed balances.
* **Multi-source updates**: Super Tokens can be updated from multiple sources, from [Money Streaming](https://docs.superfluid.org/docs/protocol/money-streaming/overview)
, but also [Distributions](https://docs.superfluid.org/docs/protocol/distributions/overview)
.
### Solution 1 (recommended): Using `balanceOf`[](https://docs.superfluid.org/docs/sdk/super-tokens/super-token-balances#solution-1-recommended-using-balanceof "Direct link to solution-1-recommended-using-balanceof")
As we mentioned earlier, Super Tokens are ERC20 compatible, so you can use the `balanceOf` function from the token smart contract to get the real time aggregated balance of a user. The Superfluid Protocol modifies the `balanceOf` function to account for the various fund movement methods unique to Super Tokens including Money Streaming and Distributions. You can simply call this function to get the real time aggregated balance of a user like so:
const fetchBlockchainBalance = async () => { setLoading(true); setError(""); try { const provider = new ethers.providers.JsonRpcProvider( "YOUR PROVIDER URL" ); const contractAddress = "0x5D8B4C2554aeB7e86F387B4d6c00Ac33499Ed01f"; //fake DAIx contract address on Mumbai const contractABI = [ "function transferFrom(address from, address to, uint value)", "function balanceOf(address owner) view returns (uint balance)", ]; const contract = new ethers.Contract( contractAddress, contractABI, provider ); const userAddress = liveAddress; const balance = await contract.balanceOf(userAddress); return(ethers.utils.formatEther(balance.toString())); } catch (error) { console.error("Error fetching blockchain balance:", error); } };
About Accuracy
We recommend this solution because it guarantees the most accurate result. However, it is important to note that this method is not always possible depending on your application architecture design.
### Solution 2: Using queries from the Subgraph[](https://docs.superfluid.org/docs/sdk/super-tokens/super-token-balances#solution-2-using-queries-from-the-subgraph "Direct link to Solution 2: Using queries from the Subgraph")
To accurately track Super Token balances, you can use the queries below to get inflows and outflow object from Superfluid's [Subgraph](https://explorer.superfluid.finance/subgraph)
.
#### Getting all the inflows for user[](https://docs.superfluid.org/docs/sdk/super-tokens/super-token-balances#getting-all-the-inflows-for-user "Direct link to Getting all the inflows for user")
query allReceivedStreams($receiver: String) { cfaStreams: streams(where: {receiver: $receiver}) { currentFlowRate streamedUntilUpdatedAt updatedAtTimestamp } gdaStreams: poolMembers(where: {account: $receiver}) { pool { totalUnits flowRate totalAmountDistributedUntilUpdatedAt updatedAtTimestamp } units totalAmountReceivedUntilUpdatedAt poolTotalAmountDistributedUntilUpdatedAt updatedAtTimestamp }}
#### Getting all the outflows for user[](https://docs.superfluid.org/docs/sdk/super-tokens/super-token-balances#getting-all-the-outflows-for-user "Direct link to Getting all the outflows for user")
query allSentStreams($sender: String) { cfaStreams: streams(where: {sender: $sender}) { currentFlowRate streamedUntilUpdatedAt updatedAtTimestamp } gdaStreams: poolDistributors(where: {account: $sender}) { flowRate updatedAtTimestamp totalAmountDistributedUntilUpdatedAt }}
Doing this allows you to do the following:
* Get **the data related to each stream a user is receiving** : This allows us to calculate the positive balance associated with each stream they receive.
* Get **the data related to each pool where the user is connected** : This allows us to calculate the positive balance associated with each membership in a pool.
* Get **the data related to each stream a user is sending** : This allows us to calculate the negative balance associated with each stream they send.
* Get **the data related to each pool where the user is distributing** : This allows us to calculate the negative balance associated with each distribution they make.
How to calculate each balance?
The rule of thumb for calculating each one of these balances is the following:
**The Balance = FlowRate \* (CurrentTime - LastUpdatedAtTime) + StreamedUntilUpdatedAt**.
Once we have the balance from each stream and each pool/distribution, we can sum them up to get the net aggregated balance of a user. An implementation of this can be seen in the `NetBalance` component below.
Click here to show `NetBalance` component
const NetBalance = ({ liveAddress }) => { const [realTimeBalance, setRealTimeBalance] = useState(null); const [blockchainBalance, setBlockchainBalance] = useState(null); const [loading, setLoading] = useState(false); const [error, setError] = useState(""); async function fetchSubgraphBalance() { setLoading(true); // Assuming setLoading is a function that updates loading state setError(""); // Assuming setError is a function that clears any previous errors const endpoint = "https://polygon-mumbai.subgraph.x.superfluid.dev"; const provider = new ethers.providers.JsonRpcProvider( "https://polygon-testnet.public.blastapi.io" ); const currentTimestamp = (await provider.getBlock("latest")).timestamp; const inflowQuery = { query: `query allReceivedStreams($receiver: String) { cfaStreams: streams(where: {receiver: $receiver}) { currentFlowRate streamedUntilUpdatedAt updatedAtTimestamp } gdaStreams: poolMembers(where: {account: $receiver}) { pool { totalUnits flowRate totalAmountDistributedUntilUpdatedAt updatedAtTimestamp } units totalAmountReceivedUntilUpdatedAt poolTotalAmountDistributedUntilUpdatedAt updatedAtTimestamp } }`, variables: { receiver: liveAddress }, }; const outflowQuery = { query: `query allSentStreams($sender: String) { cfaStreams: streams(where: {sender: $sender}) { currentFlowRate streamedUntilUpdatedAt updatedAtTimestamp } gdaStreams: poolDistributors(where: {account: $sender}) { flowRate updatedAtTimestamp totalAmountDistributedUntilUpdatedAt } }`, variables: { sender: liveAddress }, }; try { const inflowResponse = await fetch(endpoint, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(inflowQuery), }); const outflowResponse = await fetch(endpoint, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(outflowQuery), }); const inflowData = await inflowResponse.json(); const outflowData = await outflowResponse.json(); let netBalance = 0; // Calculate inflow balance inflowData.data.cfaStreams.forEach((stream) => { netBalance += parseInt(stream.currentFlowRate) * (currentTimestamp - parseInt(stream.updatedAtTimestamp)) + parseInt(stream.streamedUntilUpdatedAt); }); inflowData.data.gdaStreams.forEach((pool) => { const balance = (parseInt(pool.units) / parseInt(pool.pool.totalUnits)) * parseInt(pool.pool.flowRate) * (currentTimestamp - parseInt(pool.updatedAtTimestamp)) + parseInt(pool.totalAmountReceivedUntilUpdatedAt); netBalance += balance; }); // Calculate outflow balance (as negative) outflowData.data.cfaStreams.forEach((stream) => { netBalance -= parseInt(stream.currentFlowRate) * (currentTimestamp - parseInt(stream.updatedAtTimestamp)) + parseInt(stream.streamedUntilUpdatedAt); }); outflowData.data.gdaStreams.forEach((pool) => { const balance = parseInt(pool.flowRate) * (currentTimestamp - parseInt(pool.updatedAtTimestamp)) - parseInt(pool.totalAmountDistributedUntilUpdatedAt); netBalance -= balance; }); setRealTimeBalance(ethers.utils.formatEther(netBalance.toString())); // Assuming setRealTimeBalance is a function that updates the balance state } catch (error) { console.error("Error calculating net balance:", error); setError("Failed to calculate net balance."); // Assuming setError is a function that sets error state } finally { setLoading(false); // Assuming setLoading is a function that updates loading state } } const fetchBlockchainBalance = async () => { setLoading(true); setError(""); try { const provider = new ethers.providers.JsonRpcProvider( "https://polygon-testnet.public.blastapi.io" ); const contractAddress = "0x5D8B4C2554aeB7e86F387B4d6c00Ac33499Ed01f"; //fake DAIx contract address on Mumbai const contractABI = [ "function transferFrom(address from, address to, uint value)", "function balanceOf(address owner) view returns (uint balance)", ]; const contract = new ethers.Contract( contractAddress, contractABI, provider ); const userAddress = liveAddress; const balance = await contract.balanceOf(userAddress); setBlockchainBalance(ethers.utils.formatEther(balance.toString())); } catch (error) { console.error("Error fetching blockchain balance:", error); setError("Failed to fetch blockchain balance."); } finally { setLoading(false); } }; const handleFetch = async () => { await fetchSubgraphBalance(); await fetchBlockchainBalance(); }; return (
Real-Time Balance
Enter your liveAddress in the code editor, then click "Fetch Balance" to compare your real-time balance from the subgraph with the blockchain balance.
{error &&
{error}
} {realTimeBalance !== null && (
Real-Time Balance from Subgraph: {realTimeBalance} fake DAIx
)} {blockchainBalance !== null && (
Balance from Blockchain: {blockchainBalance} fake DAIx
)}
);};
Furthermore, you can use the live code block below to see the `NetBalance` component in action:
* Enter your `liveAddress` in the code editor.
* Click "Fetch Balance" to compare your real-time balance from the subgraph with the blockchain balance.
Live Editor
function UserBalance() {
const yourAddress\="0x5e48a37d34d93778807ef19d74e06128252bab45";
return (
);
}
Result
Loading...
About this example
Please keep in mind that in the example above we make the assumption that the user is only using Money Streaming and Distributions in the form of the GDA, but not Distributions in the form of the IDA. If you are using IDA, you will need to add a new query to get the data related to each transfer a user is distributing.
* [Compatibility with ERC20](https://docs.superfluid.org/docs/sdk/super-tokens/super-token-balances#compatibility-with-erc20)
* [Key Points](https://docs.superfluid.org/docs/sdk/super-tokens/super-token-balances#key-points)
* [Balance Tracking Considerations](https://docs.superfluid.org/docs/sdk/super-tokens/super-token-balances#balance-tracking-considerations)
* [Challenges](https://docs.superfluid.org/docs/sdk/super-tokens/super-token-balances#challenges)
* [Solution 1 (recommended): Using `balanceOf`](https://docs.superfluid.org/docs/sdk/super-tokens/super-token-balances#solution-1-recommended-using-balanceof)
* [Solution 2: Using queries from the Subgraph](https://docs.superfluid.org/docs/sdk/super-tokens/super-token-balances#solution-2-using-queries-from-the-subgraph)
---
# How to make your balance dance? | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/sdk/super-tokens/balance-dance#__docusaurus_skipToContent_fallback)
On this page
Have you ever been to the [Superfluid Dashboard](https://app.superfluid.finance/)
and seen the balance of a user dancing like in the GIF below? This is because the balance of Super Tokens is constantly being updated, with each block.

_GIF of a "Flowing Balance" from the [Superfluid Dashboard](https://app.superfluid.finance/)
_
We call this the `FlowingBalance` component and it's a great way to show the balance of a user in a dynamic and visually appealing way. In this guide, we will show you how to make your balance dance. Let's get started!
Overview[](https://docs.superfluid.org/docs/sdk/super-tokens/balance-dance#overview "Direct link to Overview")
----------------------------------------------------------------------------------------------------------------
The `FlowingBalance` component is designed to dynamically display a Super Token's balance that updates over time based on a specified flow rate, a starting balance and a starting date. This guide breaks down the component into its core functionalities, including utility functions, custom hooks, and the component itself.
`FlowingBalance` leverages React's hooks to animate balance changes over time, simulating a continuous flow of currency. It's particularly useful in applications that need to show real-time updates to a user's balance of Super Tokens, providing a visually appealing and responsive user interface.
Click here to show `FlowingBalance` Component code
import React, { useEffect, useState, useMemo, memo } from 'react';import { formatEther } from 'viem';// Constantsexport const ANIMATION_MINIMUM_STEP_TIME = 40;// Utility functionsexport const absoluteValue = (n: bigint) => { return n >= BigInt(0) ? n : -n;};export function toFixedUsingString(numStr: string, decimalPlaces: number): string { const [wholePart, decimalPart] = numStr.split('.'); if (!decimalPart || decimalPart.length <= decimalPlaces) { return numStr.padEnd(wholePart.length + 1 + decimalPlaces, '0'); } const decimalPartBigInt = BigInt(`${decimalPart.slice(0, decimalPlaces)}${decimalPart[decimalPlaces] >= '5' ? '1' : '0'}`); return `${wholePart}.${decimalPartBigInt.toString().padStart(decimalPlaces, '0')}`;}// Hooksexport const useSignificantFlowingDecimal = ( flowRate: bigint, animationStepTimeInMs: number,): number | undefined => useMemo(() => { if (flowRate === BigInt(0)) { return undefined; } const ticksPerSecond = 1000 / animationStepTimeInMs; const flowRatePerTick = flowRate / BigInt(ticksPerSecond); const [beforeEtherDecimal, afterEtherDecimal] = formatEther(flowRatePerTick).split('.'); const isFlowingInWholeNumbers = absoluteValue(BigInt(beforeEtherDecimal)) > BigInt(0); if (isFlowingInWholeNumbers) { return 0; // Flowing in whole numbers per tick. } const numberAfterDecimalWithoutLeadingZeroes = BigInt(afterEtherDecimal); const lengthToFirstSignificantDecimal = afterEtherDecimal .toString() .replace(numberAfterDecimalWithoutLeadingZeroes.toString(), '').length; // We're basically counting the zeroes. return Math.min(lengthToFirstSignificantDecimal + 2, 18); // Don't go over 18.}, [flowRate, animationStepTimeInMs]);const useFlowingBalance = ( startingBalance: bigint, startingBalanceDate: Date, flowRate: bigint) => { const [flowingBalance, setFlowingBalance] = useState(startingBalance); const startingBalanceTime = startingBalanceDate.getTime(); useEffect(() => { if (flowRate === BigInt(0)) return; let lastAnimationTimestamp = 0; const animationStep = (currentAnimationTimestamp: number) => { const animationFrameId = window.requestAnimationFrame(animationStep); if ( currentAnimationTimestamp - lastAnimationTimestamp > ANIMATION_MINIMUM_STEP_TIME ) { const elapsedTimeInMilliseconds = BigInt( Date.now() - startingBalanceTime ); const flowingBalance_ = startingBalance + (flowRate * elapsedTimeInMilliseconds) / BigInt(1000); setFlowingBalance(flowingBalance_); lastAnimationTimestamp = currentAnimationTimestamp; } return () => window.cancelAnimationFrame(animationFrameId); }; let animationFrameId = window.requestAnimationFrame(animationStep); return () => window.cancelAnimationFrame(animationFrameId); }, [startingBalance, startingBalanceTime, flowRate]); return flowingBalance;};// FlowingBalance Componentconst FlowingBalance: React.FC<{ startingBalance: bigint; startingBalanceDate: Date; flowRate: bigint;}> = memo(({ startingBalance, startingBalanceDate, flowRate }) => { const flowingBalance = useFlowingBalance( startingBalance, startingBalanceDate, flowRate ); const decimalPlaces = useSignificantFlowingDecimal( flowRate, ANIMATION_MINIMUM_STEP_TIME ); return (
);});export default FlowingBalance;
The component explicited in the code above is composed of the following parts:
* **Constants**: This section defines the minimum time interval between animation updates.
* **Utility Functions**: These functions are used to calculate the absolute value of a number and format a number to a specified number of decimal places.
* **Hooks**: These custom hooks are used to calculate the number of significant decimal places to display and update the flowing balance over time.
* **FlowingBalance Component**: This functional component uses the hooks and utility functions to render the flowing balance, taking `startingBalance`, `startingBalanceDate`, and `flowRate` as props.
Constants[](https://docs.superfluid.org/docs/sdk/super-tokens/balance-dance#constants "Direct link to Constants")
-------------------------------------------------------------------------------------------------------------------
export const ANIMATION_MINIMUM_STEP_TIME = 40;
This constant defines the minimum time interval (in milliseconds) between animation updates. It's used to throttle the animation and ensure that updates occur no more frequently than every 40 milliseconds.
Utility Functions[](https://docs.superfluid.org/docs/sdk/super-tokens/balance-dance#utility-functions "Direct link to Utility Functions")
-------------------------------------------------------------------------------------------------------------------------------------------
### `absoluteValue`[](https://docs.superfluid.org/docs/sdk/super-tokens/balance-dance#absolutevalue "Direct link to absolutevalue")
export const absoluteValue = (n: bigint) => { return n >= BigInt(0) ? n : -n;};
Converts a `bigint` to its absolute value. This function is crucial for calculations that require the non-negative form of a number.
### `toFixedUsingString`[](https://docs.superfluid.org/docs/sdk/super-tokens/balance-dance#tofixedusingstring "Direct link to tofixedusingstring")
export function toFixedUsingString(numStr: string, decimalPlaces: number): string { // Implementation details}
Formats a number (expressed as a string) to a specified number of decimal places. This function is essential for displaying the balance in a user-friendly format, ensuring that the balance is rounded and displayed with a consistent number of decimal places.
Hooks[](https://docs.superfluid.org/docs/sdk/super-tokens/balance-dance#hooks "Direct link to Hooks")
-------------------------------------------------------------------------------------------------------
### `useSignificantFlowingDecimal`[](https://docs.superfluid.org/docs/sdk/super-tokens/balance-dance#usesignificantflowingdecimal "Direct link to usesignificantflowingdecimal")
export const useSignificantFlowingDecimal = (flowRate: bigint, animationStepTimeInMs: number): number | undefined => { // Hook logic};
Determines the number of significant decimal places to display based on the flow rate and animation step time. This custom hook helps adjust the precision of the balance display dynamically, based on how quickly the balance is changing.
### `useFlowingBalance`[](https://docs.superfluid.org/docs/sdk/super-tokens/balance-dance#useflowingbalance "Direct link to useflowingbalance")
const useFlowingBalance = (startingBalance: bigint, startingBalanceDate: Date, flowRate: bigint) => { // Hook logic};
Calculates and updates the flowing balance over time. This hook is the core of the component, using the `requestAnimationFrame` API to smoothly update the balance display at a rate that's throttled by `ANIMATION_MINIMUM_STEP_TIME`.
FlowingBalance Component[](https://docs.superfluid.org/docs/sdk/super-tokens/balance-dance#flowingbalance-component "Direct link to FlowingBalance Component")
----------------------------------------------------------------------------------------------------------------------------------------------------------------
const FlowingBalance: React.FC<{startingBalance: bigint; startingBalanceDate: Date; flowRate: bigint;}> = memo(({ startingBalance, startingBalanceDate, flowRate }) => { // Component logic});
This functional component uses the above hooks and utility functions to render the flowing balance. It takes `startingBalance`, `startingBalanceDate`, and `flowRate` as props, calculating the current balance based on these inputs and displaying it in a formatted manner.
### Usage Example[](https://docs.superfluid.org/docs/sdk/super-tokens/balance-dance#usage-example "Direct link to Usage Example")
Below is an example of how to use the `FlowingBalance` component within your application.
This component exemplifies how to combine React's capabilities with the performance of the Web APIs to create dynamic and responsive UIs. By breaking down the component into its constituent parts, developers can gain insights into its functionality and customize it according to their needs.
My component is being jumpy, what can I do?
Sometimes, especially if you center your component using `justifyContent: "center"`, the component may have a jumpy behaviour like below:
❌ 10000000
If you run into this issue, you can try to set a fixed width to the component like such:
This should fix the jumpy behaviour and make the component flow smoothly like the example below:
✅ 10000000
Best practices[](https://docs.superfluid.org/docs/sdk/super-tokens/balance-dance#best-practices "Direct link to Best practices")
----------------------------------------------------------------------------------------------------------------------------------
* **Throttle the animation**: Ensure that the animation updates occur at a reasonable interval, such as every 40 milliseconds. This helps prevent excessive CPU usage and ensures a smooth user experience.
* **Use fixed width**: If the component is jumpy, consider setting a fixed width to the component to ensure a smooth flow of the balance.
* **Time conversion**: When showing the flow rate and converting the blockchain value to a human-readable value (eg. wei/s to ETH/month), ensure that the time conversion is accurate and consistent with the rest of Superfluid's time-based calculations:
* 1 year = 365 days
* 1 month = 1 year/12
* 1 day = 24 hours
* 1 hour = 60 minutes
* 1 minute = 60 seconds
* 1 second = 1000 milliseconds
* **Current timestamp**: Following Superfluid's implementation, it is recommended to use `Date.now()` to get the current timestamp in milliseconds instead of using `(await ethers.provider.getBlock('latest')).timestamp` for example.
* [Overview](https://docs.superfluid.org/docs/sdk/super-tokens/balance-dance#overview)
* [Constants](https://docs.superfluid.org/docs/sdk/super-tokens/balance-dance#constants)
* [Utility Functions](https://docs.superfluid.org/docs/sdk/super-tokens/balance-dance#utility-functions)
* [`absoluteValue`](https://docs.superfluid.org/docs/sdk/super-tokens/balance-dance#absolutevalue)
* [`toFixedUsingString`](https://docs.superfluid.org/docs/sdk/super-tokens/balance-dance#tofixedusingstring)
* [Hooks](https://docs.superfluid.org/docs/sdk/super-tokens/balance-dance#hooks)
* [`useSignificantFlowingDecimal`](https://docs.superfluid.org/docs/sdk/super-tokens/balance-dance#usesignificantflowingdecimal)
* [`useFlowingBalance`](https://docs.superfluid.org/docs/sdk/super-tokens/balance-dance#useflowingbalance)
* [FlowingBalance Component](https://docs.superfluid.org/docs/sdk/super-tokens/balance-dance#flowingbalance-component)
* [Usage Example](https://docs.superfluid.org/docs/sdk/super-tokens/balance-dance#usage-example)
* [Best practices](https://docs.superfluid.org/docs/sdk/super-tokens/balance-dance#best-practices)
---
# Subgraph | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#__docusaurus_skipToContent_fallback)
On this page
The Graph is the indexing layer of the blockchain industry, providing a queryable platform for the vast data produced by blockchain networks. The Graph can be used for querying data in the Superfluid ecosystem and other on-chain data. Experiment with queries using the [GraphQL Playground](https://thegraph.com/hosted-service/)
.
New to GraphQL?
Before diving into subgraph queries, familiarize yourself with GraphQL basics: [Learn GraphQL](https://graphql.org/learn/)
Querying Different Networks[](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#querying-different-networks "Direct link to Querying Different Networks")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
### Superfluid Explorer[](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#superfluid-explorer "Direct link to Superfluid Explorer")
The Superfluid Explorer is an interactive interface for exploring the Superfluid Protocol and interacting with its Subgraph. It provides an intuitive way to query on-chain data, get contract addresses, and manage your Superfluid finances. The console supports various blockchain networks, allowing you to seamlessly switch between them and access specific data sets. Whether you're analyzing streams, checking balances, or staying up to date with the new deployments. The Superfluid Explorer makes these tasks accessible and straightforward.
Explore Superfluid data across various networks using the Superfluid Explorer. Select a network to start querying:
* Popular
* Other
[Ethereum](https://console.superfluid.finance/subgraph?_network=ethereum)
[Polygon](https://console.superfluid.finance/subgraph?_network=matic)
[Avalanche](https://console.superfluid.finance/subgraph?_network=avalanche)
[Optimism](https://console.superfluid.finance/subgraph?_network=optimism)
[Arbitrum](https://console.superfluid.finance/subgraph?_network=arbitrum)
[Binance Smart Chain](https://console.superfluid.finance/subgraph?_network=binance-smart-chain)
For other networks, use the Superfluid Explorer:
[Superfluid Explorer](https://console.superfluid.finance/)
### Subgraph Networks[](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#subgraph-networks "Direct link to Subgraph Networks")
You can have the full list of available subgraph endpoints in the [Subgraph Endpoints](https://docs.superfluid.org/docs/technical-reference/subgraph)
page.
Resources[](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#resources "Direct link to Resources")
-----------------------------------------------------------------------------------------------------------------
* **Subgraph Queries**: [Guide on Querying the Graph](https://thegraph.com/docs/en/developer/query-the-graph/)
* **Deploy a Subgraph**: [Creating a Subgraph](https://thegraph.com/docs/en/developer/create-subgraph-hosted/)
* **GraphQL Schema**: [Superfluid Schema](https://github.com/superfluid-finance/protocol-monorepo/blob/dev/packages/subgraph/schema.graphql)
* **Our Subgraph Endpoints**: [Subgraph Endpoints](https://docs.superfluid.org/docs/technical-reference/subgraph)
Helpful Tips[](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#helpful-tips "Direct link to Helpful Tips")
--------------------------------------------------------------------------------------------------------------------------
* All addresses in the subgraph (`id`, `underlyingAddress`, etc.) are lowercase.
* Convert addresses to lowercase before querying.
### Notable Breaking Changes[](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#notable-breaking-changes "Direct link to Notable Breaking Changes")
Migrating From Legacy Subgraph to V1
Significant changes were made in October 2021:
* `totalSubscriptions` is now `totalSubscriptionsWithUnits`.
* `Subscriber` entity changed to `Subscription`.
* `createdAt` and `updatedAt` fields are now `createdAtTimestamp` and `updatedAtTimestamp`.
Schema Overview[](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#schema-overview "Direct link to Schema Overview")
-----------------------------------------------------------------------------------------------------------------------------------
The Superfluid Subgraph includes various entities for querying. Think of entities as analogous to database tables. Here's a brief overview:
### Event Entities[](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#event-entities "Direct link to Event Entities")
Event entities correspond to contract events, often with added data. Each event entity is immutable and created once.
* **Event ID Format**: `eventName-transactionHash-logIndex`.
* **Naming Convention**: For V1, event names end with 'Event'.
### Higher Order Level Entities (HOL)[](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#higher-order-level-entities-hol "Direct link to Higher Order Level Entities (HOL)")
HOL entities represent entities over their lifetime and may be updated.
* **`Account`**: Represents any address interacting with Superfluid.
* **`Token`**: Represents valid SuperTokens.
* **`Pool`**, **`PoolMember`**, **`Stream`**, **`StreamPeriod`**: Related to Superfluid streams and [pools](https://docs.superfluid.org/docs/protocol/distributions/guides/pools)
.
### Aggregate Entities[](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#aggregate-entities "Direct link to Aggregate Entities")
Aggregate entities store cumulative data at both account-token and global token levels:
* **`TokenStatistic`**: Aggregates data for a single Token type.
* **`AccountTokenSnapshot`**: Aggregates data on an account's interaction with a token.
Query Examples[](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#query-examples "Direct link to Query Examples")
--------------------------------------------------------------------------------------------------------------------------------
Here are examples to help you get started with Superfluid subgraphs:
### Super Token Data Query[](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#super-token-data-query "Direct link to Super Token Data Query")
{ tokens(first: 100) { id symbol name underlyingAddress }}
### Get All Streams for a Given Account[](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#get-all-streams-for-a-given-account "Direct link to Get All Streams for a Given Account")
To list all streams that an account is currently receiving (swap 'receiver' for 'sender' to see streams being sent):
query MyQuery { streams(where: {receiver: "YOUR_ADDRESS_HERE"}) { currentFlowRate token { symbol } sender { id } receiver { id } }}
### Getting Stream Data Between 2 Parties[](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#getting-stream-data-between-2-parties "Direct link to Getting Stream Data Between 2 Parties")
Query active streams between two parties, such as Alice ("0x658...") and Bob ("0xd66..."):
{ streams(where:{ sender: "0x658e1b019f2f30c8089a9ae3ae5820f335bd9ce4" receiver: "0xd66e40b0c30595bec72153b502ac1e0c4785991b" }) { token { id symbol } createdAtTimestamp updatedAtTimestamp currentFlowRate streamedUntilUpdatedAt }}
note
To calculate the current total amount streamed, use: _**streamedUntilUpdatedAt + ((current time in seconds) - updatedAtTimestamp) \* currentFlowRate**_.
### Get The Most Recently Updated Flows[](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#get-the-most-recently-updated-flows "Direct link to Get The Most Recently Updated Flows")
Query the 10 most recently updated flows using the `FlowUpdatedEvent` type:
{ flowUpdatedEvents(first: 10, orderBy: timestamp, orderDirection: desc) { oldFlowRate flowRate userData stream { token { symbol } sender { id } receiver { id } } }}
info
Understand the difference between a Flow and a Stream. A new stream is created each time a stream is terminated and restarted.
### Get Aggregate Flow Data For a Given Token[](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#get-aggregate-flow-data-for-a-given-token "Direct link to Get Aggregate Flow Data For a Given Token")
Query aggregate data for a specific token, such as Super DAI on Polygon:
{ tokenStatistics(where: { id: "0x1305f6b6df9dc47159d12eb7ac2804d4a33173c2" // DAIx address on Matic }) { totalNumberOfActiveStreams totalNumberOfActiveIndexes totalAmountStreamedUntilUpdatedAt totalOutflowRate totalAmountDistributedUntilUpdatedAt }}
### Get Data On a Specific Account[](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#get-data-on-a-specific-account "Direct link to Get Data On a Specific Account")
Query data on a specific account using both the `Account` and `AccountTokenSnapshot` entities:
{ accounts(where: { id: "0x..." // Enter an address below }) { isSuperApp inflows { currentFlowRate token { symbol } sender { id } } outflows { currentFlowRate token { symbol } receiver { id } } accountTokenSnapshots { token { id } totalNumberOfActiveStreams totalNetFlowRate } }}
tip
Use `AccountTokenSnapshot` to get activity data for a specific token associated with an account.
Explore more queries[](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#explore-more-queries "Direct link to Explore more queries")
--------------------------------------------------------------------------------------------------------------------------------------------------
Explore more queries using the [Superfluid Subgraph Playground](https://console.superfluid.finance/subgraph)
.
* [Querying Different Networks](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#querying-different-networks)
* [Superfluid Explorer](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#superfluid-explorer)
* [Subgraph Networks](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#subgraph-networks)
* [Resources](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#resources)
* [Helpful Tips](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#helpful-tips)
* [Notable Breaking Changes](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#notable-breaking-changes)
* [Schema Overview](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#schema-overview)
* [Event Entities](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#event-entities)
* [Higher Order Level Entities (HOL)](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#higher-order-level-entities-hol)
* [Aggregate Entities](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#aggregate-entities)
* [Query Examples](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#query-examples)
* [Super Token Data Query](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#super-token-data-query)
* [Get All Streams for a Given Account](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#get-all-streams-for-a-given-account)
* [Getting Stream Data Between 2 Parties](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#getting-stream-data-between-2-parties)
* [Get The Most Recently Updated Flows](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#get-the-most-recently-updated-flows)
* [Get Aggregate Flow Data For a Given Token](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#get-aggregate-flow-data-for-a-given-token)
* [Get Data On a Specific Account](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#get-data-on-a-specific-account)
* [Explore more queries](https://docs.superfluid.org/docs/sdk/money-streaming/subgraph#explore-more-queries)
---
# FlowSplitter Smart Contract | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/protocol/money-streaming/examples/example1#__docusaurus_skipToContent_fallback)
On this page
This guide provides an overview and usage instructions for the `FlowSplitter` smart contract, which leverages the Superfluid protocol to route incoming streams of Super Tokens to two different recipients based on predefined proportions.
Introduction[](https://docs.superfluid.org/docs/protocol/money-streaming/examples/example1#introduction "Direct link to Introduction")
----------------------------------------------------------------------------------------------------------------------------------------
The `FlowSplitter` contract is designed to automatically split incoming Super Token streams to a main and a side receiver. This splitting is determined by the `sideReceiverPortion` parameter, which defines the percentage of the incoming flow to be routed to the side receiver, with the remainder going to the main receiver.
Contract Overview[](https://docs.superfluid.org/docs/protocol/money-streaming/examples/example1#contract-overview "Direct link to Contract Overview")
-------------------------------------------------------------------------------------------------------------------------------------------------------

The above diagram illustrates how the `FlowSplitter` works. For example, if the `sideReceiverPortion` is set to 30%, then 30% of all incoming Super Token streams will be routed to the side receiver, and the remaining 70% will go to the main receiver.
Click here to show `FlowSender` contract
// SPDX-License-Identifier: UNLICENSEDpragma solidity 0.8.18;// Uncomment this line to use console.log// import "hardhat/console.sol";import {SuperTokenV1Library} from "@superfluid-finance/ethereum-contracts/contracts/apps/SuperTokenV1Library.sol";import {SuperAppBaseFlow} from "@superfluid-finance/ethereum-contracts/contracts/apps/SuperAppBaseFlow.sol";import { ISuperfluid, ISuperToken} from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol";/// @title FlowSplitter/// @author Superfluid | Modified by @0xdavinchee/// @dev A negative sideReceiverPortion portion is not allowed/// A portion > 1000 is fine though because the protocol will/// revert when trying to create a flow with a negative flow rate/// A flowRate which is less than 1000 will be rounded down to 0 and will revert/// Also an inflow which does not contain a whole number will be rounded down,/// this will also lead to a revert.contract FlowSplitter is SuperAppBaseFlow { using SuperTokenV1Library for ISuperToken; /// @dev Account that ought to be routed the majority of the inflows address public immutable MAIN_RECEIVER; /// @dev Account that ought to be routed the minority of the inflows address public immutable SIDE_RECEIVER; /// @dev Account that deployed the contract address public immutable CREATOR; /// @dev Super Token that the FlowSplitter will accept streams of ISuperToken public immutable ACCEPTED_SUPER_TOKEN; /// @dev number out of 1000 representing portion of inflows to be redirected to SIDE_RECEIVER /// Ex: 300 would represent 30% int96 public sideReceiverPortion; error INVALID_PORTION(); error SAME_RECEIVERS_NOT_ALLOWED(); error NO_SELF_FLOW(); error NOT_CREATOR(); /// @dev emitted when the split of the outflow to MAIN_RECEIVER and SIDE_RECEIVER is updated event SplitUpdated(int96 mainReceiverPortion, int96 newSideReceiverPortion); constructor( ISuperfluid host_, ISuperToken acceptedSuperToken_, address creator_, address mainReceiver_, address sideReceiver_, int96 sideReceiverPortion_ ) SuperAppBaseFlow(host_, true, true, true) { if (sideReceiverPortion_ <= 0 || sideReceiverPortion_ == 1000) revert INVALID_PORTION(); if (mainReceiver_ == sideReceiver_) revert SAME_RECEIVERS_NOT_ALLOWED(); if (mainReceiver_ == address(this) || sideReceiver_ == address(this)) revert NO_SELF_FLOW(); ACCEPTED_SUPER_TOKEN = acceptedSuperToken_; CREATOR = creator_; MAIN_RECEIVER = mainReceiver_; SIDE_RECEIVER = sideReceiver_; sideReceiverPortion = sideReceiverPortion_; } /// @dev checks that only the acceptedToken is used when sending streams into this contract /// @param superToken_ the token being streamed into the contract function isAcceptedSuperToken(ISuperToken superToken_) public view override returns (bool) { return superToken_ == ACCEPTED_SUPER_TOKEN; } /// @notice Returns the outflow rates to main and side receiver given flowRate_ and an arbitrary /// sideReceiverPortion_ /// @dev If either returns 0, it will revert when trying to create a flow /// because the protocol does not allow creating flows with a flow rate of 0 /// Also, if the sum of the two outflows is not equal to the inflow, it means the app will /// receive a residual flow. /// @param flowRate_ the inflow rate /// @param sideReceiverPortion_ the portion of the inflow to be redirected to SIDE_RECEIVER /// @return mainFlowRate the outflow rate to MAIN_RECEIVER /// @return sideFlowRate the outflow rate to SIDE_RECEIVER /// @return residualFlowRate the residual flow rate function getMainAndSideReceiverFlowRates(int96 flowRate_, int96 sideReceiverPortion_) external pure returns (int96 mainFlowRate, int96 sideFlowRate, int96 residualFlowRate) { mainFlowRate = (flowRate_ * (1000 - sideReceiverPortion_)) / 1000; sideFlowRate = (flowRate_ * sideReceiverPortion_) / 1000; residualFlowRate = flowRate_ - (mainFlowRate + sideFlowRate); } /// @notice Updates the split of the outflow to MAIN_RECEIVER and SIDE_RECEIVER /// @dev Only the creator should be able to call update split. /// @param newSideReceiverPortion_ the new portion of inflows to be redirected to SIDE_RECEIVER function updateSplit(int96 newSideReceiverPortion_) external { if (newSideReceiverPortion_ <= 0 || newSideReceiverPortion_ >= 1000) revert INVALID_PORTION(); if (msg.sender != CREATOR) revert NOT_CREATOR(); sideReceiverPortion = newSideReceiverPortion_; // get current outflow rate int96 totalOutflowRate = ACCEPTED_SUPER_TOKEN.getFlowRate(address(this), MAIN_RECEIVER) + ACCEPTED_SUPER_TOKEN.getFlowRate(address(this), SIDE_RECEIVER); int96 mainReceiverPortion = 1000 - newSideReceiverPortion_; // update outflows // @note there is a peculiar bug here where you can't change the outflow in any way ACCEPTED_SUPER_TOKEN.updateFlow(MAIN_RECEIVER, (totalOutflowRate * mainReceiverPortion) / 1000); ACCEPTED_SUPER_TOKEN.updateFlow(SIDE_RECEIVER, (totalOutflowRate * newSideReceiverPortion_) / 1000); emit SplitUpdated(mainReceiverPortion, newSideReceiverPortion_); } // --------------------------------------------------------------------------------------------- // CALLBACK LOGIC function onFlowCreated(ISuperToken superToken_, address sender_, bytes calldata ctx_) internal override returns (bytes memory newCtx) { newCtx = ctx_; // get inflow rate from sender_ int96 inflowRate = superToken_.getFlowRate(sender_, address(this)); // if there's no outflow already, create outflows if (superToken_.getFlowRate(address(this), MAIN_RECEIVER) == 0) { newCtx = superToken_.createFlowWithCtx(MAIN_RECEIVER, (inflowRate * (1000 - sideReceiverPortion)) / 1000, newCtx); newCtx = superToken_.createFlowWithCtx(SIDE_RECEIVER, (inflowRate * sideReceiverPortion) / 1000, newCtx); } // otherwise, there's already outflows which should be increased else { newCtx = superToken_.updateFlowWithCtx( MAIN_RECEIVER, ACCEPTED_SUPER_TOKEN.getFlowRate(address(this), MAIN_RECEIVER) + (inflowRate * (1000 - sideReceiverPortion)) / 1000, newCtx ); newCtx = superToken_.updateFlowWithCtx( SIDE_RECEIVER, ACCEPTED_SUPER_TOKEN.getFlowRate(address(this), SIDE_RECEIVER) + (inflowRate * sideReceiverPortion) / 1000, newCtx ); } } function onFlowUpdated( ISuperToken superToken_, address sender_, int96 previousFlowRate_, uint256, /*lastUpdated*/ bytes calldata ctx_ ) internal override returns (bytes memory newCtx) { newCtx = ctx_; // get inflow rate change from sender_ int96 inflowChange = superToken_.getFlowRate(sender_, address(this)) - previousFlowRate_; // update outflows newCtx = superToken_.updateFlowWithCtx( MAIN_RECEIVER, ACCEPTED_SUPER_TOKEN.getFlowRate(address(this), MAIN_RECEIVER) + (inflowChange * (1000 - sideReceiverPortion)) / 1000, newCtx ); newCtx = superToken_.updateFlowWithCtx( SIDE_RECEIVER, ACCEPTED_SUPER_TOKEN.getFlowRate(address(this), SIDE_RECEIVER) + (inflowChange * sideReceiverPortion) / 1000, newCtx ); } function onFlowDeleted( ISuperToken superToken_, address, /*sender_*/ address receiver_, int96 previousFlowRate_, uint256, /*lastUpdated*/ bytes calldata ctx_ ) internal override returns (bytes memory newCtx) { newCtx = ctx_; // remaining inflow is equal to total outflow less the inflow that just got deleted int96 remainingInflow = ( ACCEPTED_SUPER_TOKEN.getFlowRate(address(this), MAIN_RECEIVER) + ACCEPTED_SUPER_TOKEN.getFlowRate(address(this), SIDE_RECEIVER) ) - previousFlowRate_; // handle "rogue recipients" with sticky stream - see readme if (receiver_ == MAIN_RECEIVER || receiver_ == SIDE_RECEIVER) { newCtx = superToken_.createFlowWithCtx(receiver_, previousFlowRate_, newCtx); } // if there is no more inflow, outflows should be deleted if (remainingInflow <= 0) { newCtx = superToken_.deleteFlowWithCtx(address(this), MAIN_RECEIVER, newCtx); newCtx = superToken_.deleteFlowWithCtx(address(this), SIDE_RECEIVER, newCtx); } // otherwise, there's still inflow left and outflows must be updated else { newCtx = superToken_.updateFlowWithCtx( MAIN_RECEIVER, (remainingInflow * (1000 - sideReceiverPortion)) / 1000, newCtx ); newCtx = superToken_.updateFlowWithCtx(SIDE_RECEIVER, (remainingInflow * sideReceiverPortion) / 1000, newCtx); } }}
Key Components[](https://docs.superfluid.org/docs/protocol/money-streaming/examples/example1#key-components "Direct link to Key Components")
----------------------------------------------------------------------------------------------------------------------------------------------
* **`MAIN_RECEIVER`:** The primary account that receives the majority of the inflows.
* **`SIDE_RECEIVER`:** The secondary account that receives a smaller, specified portion of the inflows.
* **`ACCEPTED_SUPER_TOKEN`:** The specific Super Token that the `FlowSplitter` will accept for streaming.
* **`sideReceiverPortion`:** A numerical value representing the portion (out of 1000) of inflows redirected to the `SIDE_RECEIVER`.
Usage[](https://docs.superfluid.org/docs/protocol/money-streaming/examples/example1#usage "Direct link to Usage")
-------------------------------------------------------------------------------------------------------------------
### Deploying the Contract[](https://docs.superfluid.org/docs/protocol/money-streaming/examples/example1#deploying-the-contract "Direct link to Deploying the Contract")
To deploy the `FlowSplitter`, you must specify the following parameters:
* `host_`: The Superfluid host contract.
* `acceptedSuperToken_`: The Super Token to be accepted by the contract.
* `creator_`: The address of the account deploying the contract.
* `mainReceiver_`: The address of the main receiver.
* `sideReceiver_`: The address of the side receiver.
* `sideReceiverPortion_`: The initial portion of the inflow to be directed to the side receiver.
### Updating the Flow Split[](https://docs.superfluid.org/docs/protocol/money-streaming/examples/example1#updating-the-flow-split "Direct link to Updating the Flow Split")
The creator of the contract can update the flow split by calling the `updateSplit` function with a new `sideReceiverPortion_`. This adjusts the outflow rates to both receivers accordingly.
function updateSplit(int96 newSideReceiverPortion_) external;
### Calculating Flow Rates[](https://docs.superfluid.org/docs/protocol/money-streaming/examples/example1#calculating-flow-rates "Direct link to Calculating Flow Rates")
To calculate the exact outflow rates for the main and side receivers based on any inflow rate and `sideReceiverPortion`, use the `getMainAndSideReceiverFlowRates` function:
function getMainAndSideReceiverFlowRates( int96 flowRate_, int96 sideReceiverPortion_) external pure returns ( int96 mainFlowRate, int96 sideFlowRate, int96 residualFlowRate);
### Handling Streams[](https://docs.superfluid.org/docs/protocol/money-streaming/examples/example1#handling-streams "Direct link to Handling Streams")
The contract includes several internal callback functions that handle the creation, updating, and deletion of streams:
* `onFlowCreated`: Called when a new inflow to the `FlowSplitter` is created.
* `onFlowUpdated`: Called when an existing inflow to the `FlowSplitter` is updated.
* `onFlowDeleted`: Called when an inflow to the `FlowSplitter` is deleted.
Conclusion[](https://docs.superfluid.org/docs/protocol/money-streaming/examples/example1#conclusion "Direct link to Conclusion")
----------------------------------------------------------------------------------------------------------------------------------
The `FlowSplitter` smart contract offers a robust solution for automatically splitting incoming Super Token streams. By setting the `sideReceiverPortion`, users can determine the flow rates to different parties, enabling a fair and transparent distribution of funds.
* [Introduction](https://docs.superfluid.org/docs/protocol/money-streaming/examples/example1#introduction)
* [Contract Overview](https://docs.superfluid.org/docs/protocol/money-streaming/examples/example1#contract-overview)
* [Key Components](https://docs.superfluid.org/docs/protocol/money-streaming/examples/example1#key-components)
* [Usage](https://docs.superfluid.org/docs/protocol/money-streaming/examples/example1#usage)
* [Deploying the Contract](https://docs.superfluid.org/docs/protocol/money-streaming/examples/example1#deploying-the-contract)
* [Updating the Flow Split](https://docs.superfluid.org/docs/protocol/money-streaming/examples/example1#updating-the-flow-split)
* [Calculating Flow Rates](https://docs.superfluid.org/docs/protocol/money-streaming/examples/example1#calculating-flow-rates)
* [Handling Streams](https://docs.superfluid.org/docs/protocol/money-streaming/examples/example1#handling-streams)
* [Conclusion](https://docs.superfluid.org/docs/protocol/money-streaming/examples/example1#conclusion)
---
# Super Apps | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/category/super-apps#__docusaurus_skipToContent_fallback)
[📄️ Quickstart\
--------------\
\
Inroduction](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/deploy-a-super-app)
[📄️ Super Apps in Depth\
-----------------------\
\
What is a Super App?](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/understand-super-apps)
[📄️ Callbacks\
-------------\
\
Super App callbacks play a pivotal role in how Super Apps interact with the Superfluid Protocol. These callbacks are invoked in response to specific events related to Super Agreements.](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/callbacks)
[📄️ Registering Super Apps\
--------------------------\
\
Overview](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/register)
---
# Create and Manage Distribution Pools | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/sdk/distributions/create-manage-pools#__docusaurus_skipToContent_fallback)
On this page
This guide explains how to create and manage [Distribution Pools](https://docs.superfluid.org/docs/protocol/distributions/overview)
in Superfluid using the `GDAv1Forwarder` contract. Distribution pools are a key feature of Superfluid that enable scalable one-to-many and many-to-many transfers and streaming of tokens.
What are Distribution Pools?
Distribution pools are a mechanism for distributing tokens among multiple recipients. They are managed by a pool admin who controls the pool's configuration and member units. Pool members receive distributions based on their units in the pool. To learn more about distribution pools, refer to the [Distributions Overview](https://docs.superfluid.org/docs/protocol/distributions/overview)
.
Interacting with Distribution Pools from Client Applications[](https://docs.superfluid.org/docs/sdk/distributions/create-manage-pools#interacting-with-distribution-pools-from-client-applications "Direct link to Interacting with Distribution Pools from Client Applications")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
To interact with Superfluid's distribution pools from client applications, you'll use the [`GDAv1Forwarder`](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder)
contract. Here's how to set it up:
### Contract ABI and Address[](https://docs.superfluid.org/docs/sdk/distributions/create-manage-pools#contract-abi-and-address "Direct link to Contract ABI and Address")
The `GDAv1Forwarder` contract address is the same on all Superfluid chains:
0x6DA13Bde224A05a288748d857b9e7DDEffd1dE08
You can find the full ABI of the `GDAv1Forwarder` contract in the [GDAv1Forwarder technical reference](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder)
.
### Setting up with ethers.js[](https://docs.superfluid.org/docs/sdk/distributions/create-manage-pools#setting-up-with-ethersjs "Direct link to Setting up with ethers.js")
Here's how to initiate interaction with the `GDAv1Forwarder` contract using ethers.js:
import { ethers } from 'ethers';// Assuming you have a provider set up (e.g., using MetaMask)const provider = new ethers.providers.Web3Provider(window.ethereum);// The address of the GDAv1Forwarder contractconst forwarderAddress = '0x6DA13Bde224A05a288748d857b9e7DDEffd1dE08';// The ABI of the GDAv1Forwarder contract (import this from the technical reference)const forwarderABI = [...]; // Insert the ABI here// Create a contract instanceconst forwarderContract = new ethers.Contract(forwarderAddress, forwarderABI, provider.getSigner());
Understanding Distribution Pools[](https://docs.superfluid.org/docs/sdk/distributions/create-manage-pools#understanding-distribution-pools "Direct link to Understanding Distribution Pools")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Distributions is a Superfluid primitive that allows scalable one-to-many or many-to-many transfer of value, in the form of discrete transfers or Money Streaming. Superfluid's implementation of this concept allows for the creation of **Pools** with a designated **pool admin** who manages **units** for **pool members**.
Key concepts:
* **Pool**: A mechanism for distributing tokens among multiple recipients.
* **Pool Admin**: The address that has control over the pool's configuration and member units.
* **Units**: A measure of a member's share in the pool's distributions.
* **Pool Members**: Addresses that receive distributions from the pool based on their units.
Interacting with the GDAv1Forwarder Contract[](https://docs.superfluid.org/docs/sdk/distributions/create-manage-pools#interacting-with-the-gdav1forwarder-contract "Direct link to Interacting with the GDAv1Forwarder Contract")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Let's look at how to use the `GDAv1Forwarder` contract to create and manage distribution pools.
### Creating a Pool[](https://docs.superfluid.org/docs/sdk/distributions/create-manage-pools#creating-a-pool "Direct link to Creating a Pool")
To create a new Superfluid Pool, use the `createPool` function:
function createPool( ISuperfluidToken token, address admin, PoolConfig memory config) external returns (bool success, ISuperfluidPool pool)
#### Parameters[](https://docs.superfluid.org/docs/sdk/distributions/create-manage-pools#parameters "Direct link to Parameters")
* `token`: The Super Token address.
* `admin`: The pool admin address.
* `config`: The pool configuration (see below).
The `PoolConfig` struct is defined as follows:
struct PoolConfig { bool transferabilityForUnitsOwner; bool distributionFromAnyAddress;}
* `transferabilityForUnitsOwner`: If true, the pool members can transfer their owned units, else, only the pool admin can manipulate the units for pool members
* `distributionFromAnyAddress`: If true, anyone can execute distributions via the pool, else, only the pool admin can execute distributions via the pool
Strong recommendation
We don't recommend setting `transferabilityForUnitsOwner` to `true` unless you have a specific use case that absolutely requires it. This can sometimes lead to unexpected behavior and security risks.
#### Usage Example[](https://docs.superfluid.org/docs/sdk/distributions/create-manage-pools#usage-example "Direct link to Usage Example")
const createPool = async (tokenAddress, adminAddress, config) => { try { const tx = await forwarderContract.createPool(tokenAddress, adminAddress, config); const receipt = await tx.wait(); const [success, poolAddress] = receipt.events.find(e => e.event === 'PoolCreated').args; console.log("Pool created successfully:", poolAddress); return poolAddress; } catch (error) { console.error("Error creating pool:", error); }};
### Updating Member Units[](https://docs.superfluid.org/docs/sdk/distributions/create-manage-pools#updating-member-units "Direct link to Updating Member Units")
To update the units of a pool member, use the `updateMemberUnits` function:
function updateMemberUnits( ISuperfluidPool pool, address memberAddress, uint128 newUnits, bytes memory userData) external
#### Parameters[](https://docs.superfluid.org/docs/sdk/distributions/create-manage-pools#parameters-1 "Direct link to Parameters")
* `pool`: The Superfluid Pool to update.
* `memberAddress`: The address of the member to update.
* `newUnits`: The new units of the member.
* `userData`: User-specific data.
#### Usage Example[](https://docs.superfluid.org/docs/sdk/distributions/create-manage-pools#usage-example-1 "Direct link to Usage Example")
const updateMemberUnits = async (poolAddress, memberAddress, newUnits, userData) => { try { const tx = await forwarderContract.updateMemberUnits(poolAddress, memberAddress, newUnits, userData); await tx.wait(); console.log("Member units updated successfully!"); } catch (error) { console.error("Error updating member units:", error); }};
Live UI Example for Distribution Pool Management[](https://docs.superfluid.org/docs/sdk/distributions/create-manage-pools#live-ui-example-for-distribution-pool-management "Direct link to Live UI Example for Distribution Pool Management")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Here's an example of a UI component for creating and managing distribution pools:
Live Editor
function DistributionPoolManager() {
const \[tokenAddress, setTokenAddress\] \= useState(''); const \[adminAddress, setAdminAddress\] \= useState(''); const \[poolAddress, setPoolAddress\] \= useState(''); const \[memberAddress, setMemberAddress\] \= useState(''); const \[newUnits, setNewUnits\] \= useState(''); const \[walletConnected, setWalletConnected\] \= useState(false); const \[account, setAccount\] \= useState(''); const toast \= useToast();
const forwarderAddress \= '0x6DA13Bde224A05a288748d857b9e7DDEffd1dE08'; const forwarderABI \= GDAv1ForwarderABI; // You will need to import the ABI in your code. You can do that from: https://docs.superfluid.finance/docs/technical-reference/CFAv1Forwarder
const connectWallet \= async () \=> { if (typeof window.ethereum !== 'undefined') { try { await window.ethereum.request({ method: 'eth\_requestAccounts' }); const provider \= new ethers.providers.Web3Provider(window.ethereum); const signer \= provider.getSigner(); const address \= await signer.getAddress(); setAccount(address); setWalletConnected(true); toast({ title: 'Wallet connected', description: \`Connected to ${address}\`, status: 'success', duration: 3000, isClosable: true, }); } catch (error) { console.error('Failed to connect wallet:', error); toast({ title: 'Connection failed', description: 'Failed to connect wallet. Please try again.', status: 'error', duration: 3000, isClosable: true, }); } } else { toast({ title: 'Metamask not detected', description: 'Please install Metamask to use this feature.', status: 'warning', duration: 3000, isClosable: true, }); } };
const createPool \= async () \=> { if (!walletConnected) { toast({ title: 'Wallet not connected', description: 'Please connect your wallet first.', status: 'warning', duration: 3000, isClosable: true, }); return; }
const provider \= new ethers.providers.Web3Provider(window.ethereum); const signer \= provider.getSigner(); const contract \= new ethers.Contract(forwarderAddress, forwarderABI, signer);
try { // For simplicity, we're using a basic pool configuration here const config \= { transferabilityForUnitsOwner: 0, // Non-transferable distributionFromAnyAddress: false };
const tx \= await contract.createPool(tokenAddress, adminAddress, config); const receipt \= await tx.wait(); const \[success, poolAddress\] \= receipt.events.find(e \=> e.event \=== 'PoolCreated').args;
setPoolAddress(poolAddress); toast({ title: 'Pool created', description: \`Pool created successfully at ${poolAddress}\`, status: 'success', duration: 5000, isClosable: true, }); } catch (error) { console.error('Error creating pool:', error); toast({ title: 'Error', description: 'Failed to create pool. Please try again.', status: 'error', duration: 3000, isClosable: true, }); } };
const updateMemberUnits \= async () \=> { if (!walletConnected) { toast({ title: 'Wallet not connected', description: 'Please connect your wallet first.', status: 'warning', duration: 3000, isClosable: true, }); return; }
const provider \= new ethers.providers.Web3Provider(window.ethereum); const signer \= provider.getSigner(); const contract \= new ethers.Contract(forwarderAddress, forwarderABI, signer);
try { const tx \= await contract.updateMemberUnits(poolAddress, memberAddress, newUnits, "0x"); await tx.wait(); toast({ title: 'Units updated', description: 'Member units updated successfully', status: 'success', duration: 3000, isClosable: true, }); } catch (error) { console.error('Error updating member units:', error); toast({ title: 'Error', description: 'Failed to update member units. Please try again.', status: 'error', duration: 3000, isClosable: true, }); } };
return ( Distribution Pool Manager
{!walletConnected ? ( ) : ( Connected: {account} )}
Create Pool setTokenAddress(e.target.value)} /> setAdminAddress(e.target.value)} />
Update Member Units setPoolAddress(e.target.value)} /> setMemberAddress(e.target.value)} /> setNewUnits(e.target.value)} /> );
}
Result
Loading...
This UI provides the following features:
1. **Wallet Connection**: Users can connect their Ethereum wallet to interact with the Superfluid protocol.
2. **Create Pool**: Users can create a new distribution pool by providing the token address and admin address.
3. **Update Member Units**: Users can update the units of a pool member by providing the pool address, member address, and new units.
4. **Feedback**: Toast notifications inform users about the success or failure of their actions.
To use this component:
1. Click "Connect Wallet" to connect your Ethereum wallet.
2. To create a pool, enter the token address and admin address, then click "Create Pool".
3. To update member units, enter the pool address, member address, and new units, then click "Update Member Units".
This example provides a starting point for building a user interface to manage distribution pools in Superfluid. In a production environment, you would want to add more robust error checking, input validation, and additional features like displaying pool information or listing pool members.
the example does not work on your developer environment?
The example above is a live example and requires the ABI to be imported. In the case of this example, the ABI has already been imported through the live coder.
In order to make it work on your developer environment, head to the [GDAv1Forwarder technical reference](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder)
and copy the ABI. Then, replace the `forwarderABI` variable in the example with the ABI you copied.
* [Interacting with Distribution Pools from Client Applications](https://docs.superfluid.org/docs/sdk/distributions/create-manage-pools#interacting-with-distribution-pools-from-client-applications)
* [Contract ABI and Address](https://docs.superfluid.org/docs/sdk/distributions/create-manage-pools#contract-abi-and-address)
* [Setting up with ethers.js](https://docs.superfluid.org/docs/sdk/distributions/create-manage-pools#setting-up-with-ethersjs)
* [Understanding Distribution Pools](https://docs.superfluid.org/docs/sdk/distributions/create-manage-pools#understanding-distribution-pools)
* [Interacting with the GDAv1Forwarder Contract](https://docs.superfluid.org/docs/sdk/distributions/create-manage-pools#interacting-with-the-gdav1forwarder-contract)
* [Creating a Pool](https://docs.superfluid.org/docs/sdk/distributions/create-manage-pools#creating-a-pool)
* [Updating Member Units](https://docs.superfluid.org/docs/sdk/distributions/create-manage-pools#updating-member-units)
* [Live UI Example for Distribution Pool Management](https://docs.superfluid.org/docs/sdk/distributions/create-manage-pools#live-ui-example-for-distribution-pool-management)
---
# Automations | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/category/automations#__docusaurus_skipToContent_fallback)
[📄️ Auto-Wrap\
-------------\
\
What's Auto-Wrap?](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/auto-wrap)
[📄️ Stream Scheduler\
--------------------\
\
What’s the Stream Scheduler?](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/stream-scheduler)
[📄️ Vesting Scheduler\
---------------------\
\
What’s the Vesting Scheduler?](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/vesting-scheduler)
[📄️ Stream Accounting API\
-------------------------\
\
Overview](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/stream-accounting-api)
---
# Advertisement Auction DApp | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/protocol/examples/example1#__docusaurus_skipToContent_fallback)
On this page
This guide explores the development of a decentralized application (DApp) for an advertisement auction system, leveraging the capabilities of Superfluid's [Distribution Pools](https://docs.superfluid.org/docs/protocol/distributions/guides/pools)
(also called the _General Distributions Agreement - GDA_).
Overview[](https://docs.superfluid.org/docs/protocol/examples/example1#overview "Direct link to Overview")
------------------------------------------------------------------------------------------------------------
In the ever-evolving landscape of digital advertising, there's a need for more dynamic and efficient systems. Traditional models often involve complex, non-transparent payment structures and lack real-time interaction capabilities. Our DApp aims to address these challenges by using Distributions from Superfluid Protocol for seamless transactions and fair distribution of advertising revenues.
This example addresses the following Superfluid Protocol features:
* [Money Streaming](https://docs.superfluid.org/docs/protocol/money-streaming/overview)
* [Distribution Pools](https://docs.superfluid.org/docs/protocol/distributions/guides/pools)
* [Super Apps](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/deploy-a-super-app)
Check out the full codebase
For the complete implementation of the DApp, including the smart contract and foundry test, refer to the [GitHub repository](https://github.com/superfluid-finance/ad-auction-example)
.
### The Problem[](https://docs.superfluid.org/docs/protocol/examples/example1#the-problem "Direct link to The Problem")
The main challenges in current digital advertising models include:
1. **Lack of Transparency**: Difficulty in tracking funds and understanding distribution mechanisms.
2. **Inefficient Payment Systems**: Cumbersome processes for handling and distributing advertising revenue.
3. **Static Advertisement Bidding**: Traditional models don't allow real-time bidding, leading to less engagement and fairness.
### Our Solution[](https://docs.superfluid.org/docs/protocol/examples/example1#our-solution "Direct link to Our Solution")
Our DApp introduces a novel approach to advertisement auctioning:
* **Continuous Funds Stream**: Utilizing Superfluid's money streaming concept, funds flow continuously into a distribution pool.
* **Dynamic Advertisement Auctioning**: Advertisers bid for ad space in real-time through streaming payments, creating an engaging and fair auction system.
* **Proportional Distribution**: Funds are distributed between the DApp owner and previous advertisers based on their advertising duration, ensuring fair compensation.
_Visualization of our advertisement auction app mechanism_
note
In the visualization above we see how the previous streamer joins the pool to become a new member and get money streamed to him
### Smart Contract Structure[](https://docs.superfluid.org/docs/protocol/examples/example1#smart-contract-structure "Direct link to Smart Contract Structure")
The `AdSpotContract` is at the heart of our DApp, built on Ethereum and integrated with Superfluid Protocol. It encompasses:
* **Pool Creation and Management**: Facilities for users to create and administer distribution pools.
* **Auction Mechanism**: Mechanisms for real-time bidding and advertisement space allocation.
* **Fund Distribution Logic**: Automated and transparent distribution of funds between DApp owners and advertisers.
* **Superfluid Integration**: Leveraging Superfluid's GDA for efficient streaming of funds.
In the following sections, we'll delve deeper into each aspect of the DApp, providing insights into the smart contract functionalities, implementation guide, and UI/UX considerations.
note
This guide is intended for blockchain developers and assumes familiarity with Ethereum smart contract development and minimal familiarity with the concept of [Distribution Pools](https://docs.superfluid.org/docs/protocol/distributions/guides/pools)
.
Smart Contract Implementation[](https://docs.superfluid.org/docs/protocol/examples/example1#smart-contract-implementation "Direct link to Smart Contract Implementation")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
The [`AdSpotContract`](https://github.com/superfluid-finance/ad-auction-example/blob/master/src/AdSpotContract.sol)
plays a crucial role in our DApp, integrating Superfluid's streaming capabilities for an innovative advertisement auction system. Let's dive into the key components and functionalities of this smart contract.
### Contract Overview[](https://docs.superfluid.org/docs/protocol/examples/example1#contract-overview "Direct link to Contract Overview")
This guide demonstrates how to use the Superfluid Protocol's [Distribution Pools](https://docs.superfluid.org/docs/protocol/distributions/guides/pools)
(also known as the GDA in our codebase) to develop a decentralized application (DApp) for advertisement auctioning. We'll walk through the key components of the `AdSpotContract`.
Contract Initialization[](https://docs.superfluid.org/docs/protocol/examples/example1#contract-initialization "Direct link to Contract Initialization")
---------------------------------------------------------------------------------------------------------------------------------------------------------
The `AdSpotContract` is initialized with necessary Superfluid interfaces and parameters. Here's a look at the constructor:
constructor(ISuperToken _acceptedToken) CFASuperAppBase(ISuperfluid(_acceptedToken.getHost())){ // Contract initialization code}
This constructor sets up the Superfluid context and initializes the fund distribution pool.
Real-Time Auctioning Logic[](https://docs.superfluid.org/docs/protocol/examples/example1#real-time-auctioning-logic "Direct link to Real-Time Auctioning Logic")
------------------------------------------------------------------------------------------------------------------------------------------------------------------
The contract employs callback functions to manage auction logic. Here's an example of a callback function handling new flow creation:
function onFlowCreated( ISuperToken /*superToken*/, address sender, bytes calldata ctx) internal override returns (bytes memory newCtx) { // Logic for handling new flow creation}
These functions are crucial for updating the highest bidder and managing the distribution of shares.
NFT Showcase Feature[](https://docs.superfluid.org/docs/protocol/examples/example1#nft-showcase-feature "Direct link to NFT Showcase Feature")
------------------------------------------------------------------------------------------------------------------------------------------------
The contract also includes a feature for the highest bidder to showcase an NFT:
function setNftToShowcase(address _nftAddress, uint256 _tokenId) external { // NFT showcase logic}
This feature adds interactivity to the advertisement space, allowing for dynamic content display.
Getters for Contract State[](https://docs.superfluid.org/docs/protocol/examples/example1#getters-for-contract-state "Direct link to Getters for Contract State")
------------------------------------------------------------------------------------------------------------------------------------------------------------------
Various getter functions provide important information about the contract's state:
function getHighestBidder() public view returns (address) { // Logic to retrieve the highest bidder}
These functions are essential for users to interact with and understand the contract's current state.
info
For a complete code base and tests of the `AdSpotContract`, refer to the [full contract code](https://github.com/superfluid-finance/ad-auction-example/)
.
Conclusion[](https://docs.superfluid.org/docs/protocol/examples/example1#conclusion "Direct link to Conclusion")
------------------------------------------------------------------------------------------------------------------
This guide provided a high-level overview of the `AdSpotContract` used in a DApp for advertisement auctioning with Superfluid. The contract demonstrates a real-time auction mechanism, a dynamic NFT showcase feature, and efficient fund distribution using Superfluid's streaming capabilities.
* [Overview](https://docs.superfluid.org/docs/protocol/examples/example1#overview)
* [The Problem](https://docs.superfluid.org/docs/protocol/examples/example1#the-problem)
* [Our Solution](https://docs.superfluid.org/docs/protocol/examples/example1#our-solution)
* [Smart Contract Structure](https://docs.superfluid.org/docs/protocol/examples/example1#smart-contract-structure)
* [Smart Contract Implementation](https://docs.superfluid.org/docs/protocol/examples/example1#smart-contract-implementation)
* [Contract Overview](https://docs.superfluid.org/docs/protocol/examples/example1#contract-overview)
* [Contract Initialization](https://docs.superfluid.org/docs/protocol/examples/example1#contract-initialization)
* [Real-Time Auctioning Logic](https://docs.superfluid.org/docs/protocol/examples/example1#real-time-auctioning-logic)
* [NFT Showcase Feature](https://docs.superfluid.org/docs/protocol/examples/example1#nft-showcase-feature)
* [Getters for Contract State](https://docs.superfluid.org/docs/protocol/examples/example1#getters-for-contract-state)
* [Conclusion](https://docs.superfluid.org/docs/protocol/examples/example1#conclusion)
---
# Solvency | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/category/solvency#__docusaurus_skipToContent_fallback)
[📄️ Liquidations & TOGA\
-----------------------\
\
Liquidation and Solvency](https://docs.superfluid.org/docs/protocol/advanced-topics/solvency/liquidations-and-toga)
[📄️ Running a Sentinel\
----------------------\
\
In our section on Liquidations & TOGA, we described how the Superfluid protocol handles solvency & liquidations. Sentinels play a vital role in this process. This page provides links to various resources that will aid you on your journey to help secure the protocol 🛡⚔️](https://docs.superfluid.org/docs/protocol/advanced-topics/solvency/running-a-sentinnel)
[📄️ Solvency Dashboard\
----------------------\
\
Click on the link below to find the solvency dashboard for the Superfluid protocol.](https://docs.superfluid.org/docs/protocol/advanced-topics/solvency/solvency-dashboard)
---
# Batch transactions with Macros | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-macro#__docusaurus_skipToContent_fallback)
On this page
Superfluid's infrastructure introduces innovative approaches to batching transactions and account abstraction, leveraging the [modular architrecture](https://docs.superfluid.org/docs/technical-reference/Architecture)
of Superfluid, and specifically the mastermind contract of the protocol called the [Superfluid Host](https://docs.superfluid.org/docs/concepts/advanced-topics/superfluid-host)
. This document provides a guide of how to use the MacroForwarder contract to batch transactions.
Background[](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-macro#background "Direct link to Background")
-----------------------------------------------------------------------------------------------------------------------------
The Superfluid Host contract makes it possible to batch transactions from day one through a method called `batchCall`. Eventually, the Superfluid Host adopted [ERC-2771](https://eips.ethereum.org/EIPS/eip-2771)
. As opposed to the [EIP-4337](https://ethereum.org/en/roadmap/account-abstraction)
which uses a Contract Account (CA) for abstraction, ERC-2771 extends the capabilities of the Host by allowing a trusted forwarder to pass the original `msg.sender` to the host contract through the method `forwardBatchCall`.
Macro Forwarder Contract Overview[](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-macro#macro-forwarder-contract-overview "Direct link to Macro Forwarder Contract Overview")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Introducing a simple and secure way for builders to define their own macros without needing to be directly trusted by the Superfluid host contract. This approach simplifies on-chain logic for batch calls, reduces gas consumption and potentially ameliorates the front-end code, addressing atomicity issues. Today, Superfluid has a contract called [`MacroForwarder.sol`](https://github.com/superfluid-finance/protocol-monorepo/blob/dev/packages/ethereum-contracts/contracts/utils/MacroForwarder.sol)
which is a trusted forwarder for user-defined macro interfaces.
Click here to show the `MacroForwarder` contract
// SPDX-License-Identifier: AGPLv3pragma solidity 0.8.23;import { IUserDefinedMacro } from "../interfaces/utils/IUserDefinedMacro.sol";import { ISuperfluid } from "../interfaces/superfluid/ISuperfluid.sol";import { ForwarderBase } from "../utils/ForwarderBase.sol";/** * @dev This is a trusted forwarder with high degree of extensibility through permission-less and user-defined "macro * contracts". This is a vanilla version without EIP-712 support. */contract MacroForwarder is ForwarderBase { constructor(ISuperfluid host) ForwarderBase(host) {} /** * @dev A convenience view wrapper for building the batch operations using a macro. * @param m Target macro. * @param params Parameters to simulate the macro. * @return operations Operations returned by the macro after the simulation. */ function buildBatchOperations(IUserDefinedMacro m, bytes calldata params) public view returns (ISuperfluid.Operation[] memory operations) { operations = m.buildBatchOperations(_host, params, msg.sender); } /** * @dev Run the macro defined by the provided macro contract and params. * @param m Target macro. * @param params Parameters to run the macro. */ function runMacro(IUserDefinedMacro m, bytes calldata params) external returns (bool) { ISuperfluid.Operation[] memory operations = buildBatchOperations(m, params); return _forwardBatchCall(operations); }}
### Macro Forwarder Contract Address[](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-macro#macro-forwarder-contract-address "Direct link to Macro Forwarder Contract Address")
The `MacroForwarder` contract has the same address on all networks:
0xFD0268E33111565dE546af2675351A4b1587F89F
### Macro Forwarder Contract ABI[](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-macro#macro-forwarder-contract-abi "Direct link to Macro Forwarder Contract ABI")
In order to interact with the `MacroForwarder` contract from your client application, you can use the following ABI:
Click here to show the `MacroForwarder` ABI
[ { "inputs": [ { "internalType": "contract ISuperfluid", "name": "host", "type": "address" } ], "stateMutability": "nonpayable", "type": "constructor" }, { "inputs": [ { "internalType": "contract IUserDefinedMacro", "name": "m", "type": "address" }, { "internalType": "bytes", "name": "params", "type": "bytes" } ], "name": "buildBatchOperations", "outputs": [ { "components": [ { "internalType": "uint32", "name": "operationType", "type": "uint32" }, { "internalType": "address", "name": "target", "type": "address" }, { "internalType": "bytes", "name": "data", "type": "bytes" } ], "internalType": "struct ISuperfluid.Operation[]", "name": "operations", "type": "tuple[]" } ], "stateMutability": "view", "type": "function" }, { "inputs": [ { "internalType": "contract IUserDefinedMacro", "name": "m", "type": "address" }, { "internalType": "bytes", "name": "params", "type": "bytes" } ], "name": "runMacro", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "nonpayable", "type": "function" }]
How to use the Macro Forwarder[](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-macro#how-to-use-the-macro-forwarder "Direct link to How to use the Macro Forwarder")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
In order to understand how to use the `MacroForwarder` contract, we will use an example contract called `MultiFlowDeleteMacro.sol` which allows us to batch call delete flow transactions from one account to multiple accounts for a specific Super Token:
Click here to show the `MultiFlowDeleteMacro` contract
// SPDX-License-Identifier: AGPLv3pragma solidity 0.8.23;import { ISuperfluid, BatchOperation, IConstantFlowAgreementV1, ISuperToken } from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol";import { IUserDefinedMacro } from "@superfluid-finance/ethereum-contracts/contracts/interfaces/utils/IUserDefinedMacro.sol";// deletes a bunch of flows of the msgSendercontract MultiFlowDeleteMacro is IUserDefinedMacro { function buildBatchOperations(ISuperfluid host, bytes memory params, address msgSender) public virtual view returns (ISuperfluid.Operation[] memory operations) { IConstantFlowAgreementV1 cfa = IConstantFlowAgreementV1(address(host.getAgreementClass( keccak256("org.superfluid-finance.agreements.ConstantFlowAgreement.v1") ))); // parse params (ISuperToken token, address[] memory receivers) = abi.decode(params, (ISuperToken, address[])); // construct batch operations operations = new ISuperfluid.Operation[](receivers.length); for (uint i = 0; i < receivers.length; ++i) { bytes memory callData = abi.encodeCall(cfa.deleteFlow, (token, msgSender, receivers[i], new bytes(0) // placeholder )); operations[i] = ISuperfluid.Operation({ operationType : BatchOperation.OPERATION_TYPE_SUPERFLUID_CALL_AGREEMENT, // type target: address(cfa), data: abi.encode(callData, new bytes(0)) }); } } // returns the abi encoded params for the macro, to be used with buildBatchOperations function getParams(ISuperToken superToken, address[] memory receivers) external pure returns (bytes memory) { return abi.encode(superToken, receivers); } // postCheck is a function that is called after the batch operations are executed function postCheck(ISuperfluid host, bytes memory params, address msgSender) external view{ }}
The steps in order to use the `MacroForwarder` contract are as follows:
1. Create a contract which inherit the User Defined Macro Interface
2. Implement your Macro Interface
3. Use the Macro Forwarder to batch call the transactions
Get ready for tests and deployment
Creating your own macro involves testing and deploying a smart contract. If you are not familiar with testing and deployment frameworks on the Ethereum Virtual Machine, you should consider learning about [Hardhat](https://hardhat.org/)
or [Foundry](https://book.getfoundry.sh/)
.
### 1\. Create your contract and inherit the User Defined Macro Interface[](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-macro#1-create-your-contract-and-inherit-the-user-defined-macro-interface "Direct link to 1. Create your contract and inherit the User Defined Macro Interface")
As you may have noticed, the `MultiFlowDeleteMacro` contract inherits the `IUserDefinedMacro` interface like so:
contract MultiFlowDeleteMacro is IUserDefinedMacro { ...}
This is an interface that defines the `buildBatchOperations` method. It is the only required method to be implemented in the contract that inherits it.
Therefore, the first step is to create a new contract which inherits the `IUserDefinedMacro` interface.
### 2\. Implement your Macro Interface[](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-macro#2-implement-your-macro-interface "Direct link to 2. Implement your Macro Interface")
The `buildBatchOperations` method is the only required method to be implemented in the contract that inherits the `IUserDefinedMacro` interface. This method returns an array of `ISuperfluid.Operation[]` struct which will be consumed by the `MacroForwarder` contract. This struct is defined as follows:
struct Operation { operationType operationType; address target; bytes data;}
In the example contract `MultiFlowDeleteMacro`, you can see that the `buildBatchOperations` method is implemented as follows:
function buildBatchOperations(ISuperfluid host, bytes memory params, address msgSender) public virtual view returns (ISuperfluid.Operation[] memory operations) { IConstantFlowAgreementV1 cfa = IConstantFlowAgreementV1(address(host.getAgreementClass( keccak256("org.superfluid-finance.agreements.ConstantFlowAgreement.v1") ))); // parse params (ISuperToken token, address[] memory receivers) = abi.decode(params, (ISuperToken, address[])); // construct batch operations operations = new ISuperfluid.Operation[](receivers.length); for (uint i = 0; i < receivers.length; ++i) { bytes memory callData = abi.encodeCall(cfa.deleteFlow, (token, msgSender, receivers[i], new bytes(0) // placeholder )); operations[i] = ISuperfluid.Operation({ operationType : BatchOperation.OPERATION_TYPE_SUPERFLUID_CALL_AGREEMENT, // type target: address(cfa), data: abi.encode(callData, new bytes(0)) }); } }
About the method `getParams`
The `MultiFlowDeleteMacro` example contract contains a method called `getParams`. This method is not required to be implemented in the contract that inherits the `IUserDefinedMacro` interface. However, it is highly recommended to implement this method in order to parse the parameters of the macro on the front-end.
This method is simply implemented by encoding the parameters that will be used to call the method `runMacro`from `MacroForwarder` contract. It is usually one line of code as such:
function getParams(ISuperToken token, address[] memory receivers) public pure returns (bytes memory) { return abi.encode(token, receivers);}
Once, you set up and tested your Macro contract, you can deploy it to your target EVM network and use the `MacroForwarder` contract to batch call the transactions.
### 3\. Use the Macro Forwarder to batch call the transactions[](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-macro#3-use-the-macro-forwarder-to-batch-call-the-transactions "Direct link to 3. Use the Macro Forwarder to batch call the transactions")
The `MacroForwarder` contract is used to batch call the transactions. It is a simple contract that has a method called `runMacro` which takes the following parameters:
* `IUserDefinedMacro m`: The address of the contract that inherits the `IUserDefinedMacro` interface
* `bytes calldata params`: The parameters of the macro
The `runMacro` method is called by the user and it will batch call the transactions defined in the `buildBatchOperations` method of the `IUserDefinedMacro` contract.
To showcase how this works, we use the [`MacroFowarder` contract](https://sepolia-optimism.etherscan.io/address/0xFD0268E33111565dE546af2675351A4b1587F89F)
deployed on OP Sepolia. We deployed an example of our [`MultiFlowDeleteMacro` contract](https://sepolia-optimism.etherscan.io/address/0x997b37Fb47c489CF067421aEeAf7Be0543fA5362)
on the same network. We will use the `MacroForwarder` contract to batch call the transactions.
We showcase below a simple React component which implements all of this:
Click here to show the `MacroForwarderComponent`
const MacroForwarderComponent = ({ macroForwarderAddress, userDefinedMacroAddress,}) => { const [walletAddress, setWalletAddress] = useState(""); const [superToken, setSuperToken] = useState(""); const [receivers, setReceivers] = useState(""); const [message, setMessage] = useState(""); // ABI for MacroForwarder contract including `runMacro` const macroForwarderABI = [ //ABI for MacroForwarder contract ]; // ABI for your UserDefinedMacro including `getParams` const iUserDefinedMacroABI = [ //ABI for your UserDefinedMacro including `getParams` ]; const connectWallet = async () => { if (window.ethereum) { try { const provider = new ethers.providers.Web3Provider(window.ethereum); await provider.send("eth_requestAccounts", []); const signer = provider.getSigner(); const address = await signer.getAddress(); setWalletAddress(address); console.log("Connected to MetaMask"); } catch (error) { console.error("Error connecting to MetaMask", error); setMessage("Error connecting to MetaMask"); } } else { console.log("Ethereum wallet is not connected or not installed."); setMessage("Ethereum wallet is not connected or not installed."); } }; const executeMacro = async () => { try { if (!walletAddress) throw new Error("Wallet not connected."); const provider = new ethers.providers.Web3Provider(window.ethereum); const signer = provider.getSigner(); const userDefinedMacroContract = new ethers.Contract( userDefinedMacroAddress, iUserDefinedMacroABI, signer ); const receiversArray = receivers .split(",") .map((address) => address.trim()); const params = await userDefinedMacroContract.getParams( superToken, receiversArray ); const macroForwarderContract = new ethers.Contract( macroForwarderAddress, macroForwarderABI, signer ); const tx = await macroForwarderContract.runMacro( userDefinedMacroAddress, params ); await tx.wait(); setMessage("Macro executed successfully."); } catch (error) { console.error("Error executing macro", error); setMessage(`Error: ${error.message}`); } }; return (
Macro Forwarder Interface
Connect Wallet to your chosen testnet (e.g. OP Sepolia)
);};
The `MacroForwarderComponent` is a simple React component that allows you to connect your wallet and execute the macro using EthersJS. If you deployed your own `MultiFlowDeleteMacro` contract, you can use the `MacroForwarderComponent` to batch call the transactions by inputing the `MacroForwarder` and `MultiFlowDeleteMacro` contract addresses in the playground below.
Live Editor
function MacroComponentExample() {
const macroForwarderAddress\="0xFD0268E33111565dE546af2675351A4b1587F89F";
const userMacroAddress\="0x997b37Fb47c489CF067421aEeAf7Be0543fA5362";
return (
);
}
Result
Loading...
Next Steps - EIP-712 Support[](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-macro#next-steps---eip-712-support "Direct link to Next Steps - EIP-712 Support")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
We will provide a guide which laverages [EIP-712](https://eips.ethereum.org/EIPS/eip-712)
for typed structured data hashing and signing, enhancing the security and usability of macro transactions. This will allow for the following features:
* On-chain verifiable signatures.
* Multilingual support for transaction signing.
* Supports meta transactions, allowing for gas-less transactions.
* And more...
* [Background](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-macro#background)
* [Macro Forwarder Contract Overview](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-macro#macro-forwarder-contract-overview)
* [Macro Forwarder Contract Address](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-macro#macro-forwarder-contract-address)
* [Macro Forwarder Contract ABI](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-macro#macro-forwarder-contract-abi)
* [How to use the Macro Forwarder](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-macro#how-to-use-the-macro-forwarder)
* [1\. Create your contract and inherit the User Defined Macro Interface](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-macro#1-create-your-contract-and-inherit-the-user-defined-macro-interface)
* [2\. Implement your Macro Interface](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-macro#2-implement-your-macro-interface)
* [3\. Use the Macro Forwarder to batch call the transactions](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-macro#3-use-the-macro-forwarder-to-batch-call-the-transactions)
* [Next Steps - EIP-712 Support](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-macro#next-steps---eip-712-support)
---
# Connecting and Claiming from the Pools | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/sdk/distributions/connect-claim-pool#__docusaurus_skipToContent_fallback)
On this page
This guide focuses on connecting and claiming from Superfluid [Distribution Pools](https://docs.superfluid.org/docs/concepts/overview/distributions)
using the `GDAv1Forwarder` contract. You'll learn how to interact with Superfluid pools from client applications. We will specifically show how you can connect members to pools, and claim tokens from them.
Interacting with the Superfluid Protocol[](https://docs.superfluid.org/docs/sdk/distributions/connect-claim-pool#interacting-with-the-superfluid-protocol "Direct link to Interacting with the Superfluid Protocol")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
To interact with Superfluid's distribution pools from client applications, you'll use the `GDAv1Forwarder` contract. Here's how to set it up:
### Contract ABI and Address[](https://docs.superfluid.org/docs/sdk/distributions/connect-claim-pool#contract-abi-and-address "Direct link to Contract ABI and Address")
The `GDAv1Forwarder` contract address is the same on all Superfluid chains:
0x6DA13Bde224A05a288748d857b9e7DDEffd1dE08
You can find the full ABI of the `GDAv1Forwarder` contract in the [GDAv1Forwarder technical reference](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder)
.
### Setting up with ethers.js[](https://docs.superfluid.org/docs/sdk/distributions/connect-claim-pool#setting-up-with-ethersjs "Direct link to Setting up with ethers.js")
Here's how to initiate interaction with the `GDAv1Forwarder` contract using ethers.js:
import { ethers } from 'ethers';// Assuming you have a provider set up (e.g., using MetaMask)const provider = new ethers.providers.Web3Provider(window.ethereum);// The address of the GDAv1Forwarder contractconst forwarderAddress = '0x6DA13Bde224A05a288748d857b9e7DDEffd1dE08';// The ABI of the GDAv1Forwarder contract (import this from the technical reference)const forwarderABI = [...]; // Insert the ABI here// Create a contract instanceconst forwarderContract = new ethers.Contract(forwarderAddress, forwarderABI, provider.getSigner());
Understanding Connecting and Claiming[](https://docs.superfluid.org/docs/sdk/distributions/connect-claim-pool#understanding-connecting-and-claiming "Direct link to Understanding Connecting and Claiming")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
When interacting with Superfluid pools, it's important to understand the difference between connecting to a pool and claiming from it:
1. **Connecting to a Pool**:
* When a member connects to a pool, they start receiving streams and transfers in real-time.
* The member's balance will automatically reflect incoming tokens without any further action.
* This is ideal for continuous, real-time token distribution.
2. **Claiming from a Pool**:
* Claiming is the process of explicitly withdrawing accumulated tokens from the pool.
* Members can claim periodically to move tokens from the pool to their personal balance.
* This is useful for members who prefer to manually manage their token receipts or for specific accounting purposes.
In essence, connecting provides a passive, continuous flow of tokens, while claiming is an active process to withdraw accumulated tokens.
Interacting with the GDAv1Forwarder Contract[](https://docs.superfluid.org/docs/sdk/distributions/connect-claim-pool#interacting-with-the-gdav1forwarder-contract "Direct link to Interacting with the GDAv1Forwarder Contract")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Let's look at how to use the `GDAv1Forwarder` contract to connect, disconnect, and claim from pools.
### Connecting to a Pool[](https://docs.superfluid.org/docs/sdk/distributions/connect-claim-pool#connecting-to-a-pool "Direct link to Connecting to a Pool")
To connect a member to a pool, use the `connectPool` function:
function connectPool( ISuperfluidPool pool, bytes memory userData) external returns (bool)
#### Parameters[](https://docs.superfluid.org/docs/sdk/distributions/connect-claim-pool#parameters "Direct link to Parameters")
* `pool`: The Superfluid Pool to connect.
* `userData`: User-specific data.
#### Usage Example[](https://docs.superfluid.org/docs/sdk/distributions/connect-claim-pool#usage-example "Direct link to Usage Example")
const connectPool = async (poolAddress, userData = "0x") => { try { const tx = await forwarderContract.connectPool(poolAddress, userData); const receipt = await tx.wait(); console.log("Successfully connected to pool"); return receipt.status === 1; // 1 indicates success } catch (error) { console.error("Error connecting to pool:", error); return false; }};
Connecting triggers a claim
When a member connects to a pool, the contract automatically claims all the previously available tokens for the member.
### Disconnecting from a Pool[](https://docs.superfluid.org/docs/sdk/distributions/connect-claim-pool#disconnecting-from-a-pool "Direct link to Disconnecting from a Pool")
To disconnect a member from a pool, use the `disconnectPool` function:
function disconnectPool( ISuperfluidPool pool, bytes memory userData) external returns (bool)
#### Parameters[](https://docs.superfluid.org/docs/sdk/distributions/connect-claim-pool#parameters-1 "Direct link to Parameters")
* `pool`: The Superfluid Pool to disconnect.
* `userData`: User-specific data.
#### Usage Example[](https://docs.superfluid.org/docs/sdk/distributions/connect-claim-pool#usage-example-1 "Direct link to Usage Example")
const disconnectPool = async (poolAddress, userData = "0x") => { try { const tx = await forwarderContract.disconnectPool(poolAddress, userData); const receipt = await tx.wait(); console.log("Successfully disconnected from pool"); return receipt.status === 1; // 1 indicates success } catch (error) { console.error("Error disconnecting from pool:", error); return false; }};
### Claiming All Tokens from a Pool[](https://docs.superfluid.org/docs/sdk/distributions/connect-claim-pool#claiming-all-tokens-from-a-pool "Direct link to Claiming All Tokens from a Pool")
To claim all available tokens for a member from a pool, use the `claimAll` function:
function claimAll( ISuperfluidPool pool, address memberAddress, bytes memory userData) external
#### Parameters[](https://docs.superfluid.org/docs/sdk/distributions/connect-claim-pool#parameters-2 "Direct link to Parameters")
* `pool`: The Superfluid Pool to claim from.
* `memberAddress`: The address of the member to claim for.
* `userData`: User-specific data.
#### Usage Example[](https://docs.superfluid.org/docs/sdk/distributions/connect-claim-pool#usage-example-2 "Direct link to Usage Example")
const claimAll = async (poolAddress, memberAddress, userData = "0x") => { try { const tx = await forwarderContract.claimAll(poolAddress, memberAddress, userData); await tx.wait(); console.log("Successfully claimed all tokens from pool"); return true; } catch (error) { console.error("Error claiming tokens from pool:", error); return false; }};
Live UI Example for Pool Interaction[](https://docs.superfluid.org/docs/sdk/distributions/connect-claim-pool#live-ui-example-for-pool-interaction "Direct link to Live UI Example for Pool Interaction")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Here's an example of a UI component for connecting, disconnecting, and claiming from Superfluid pools:
Live Editor
function PoolInteractionManager() {
const \[poolAddress, setPoolAddress\] \= useState(''); const \[memberAddress, setMemberAddress\] \= useState(''); const \[walletConnected, setWalletConnected\] \= useState(false); const \[account, setAccount\] \= useState(''); const toast \= useToast();
const forwarderAddress \= '0x6DA13Bde224A05a288748d857b9e7DDEffd1dE08'; const forwarderABI \= GDAv1ForwarderABI; // You will need to import the ABI in your code. You can do that from: https://docs.superfluid.finance/docs/technical-reference/CFAv1Forwarder
const connectWallet \= async () \=> { if (typeof window.ethereum !== 'undefined') { try { await window.ethereum.request({ method: 'eth\_requestAccounts' }); const provider \= new ethers.providers.Web3Provider(window.ethereum); const signer \= provider.getSigner(); const address \= await signer.getAddress(); setAccount(address); setWalletConnected(true); toast({ title: 'Wallet connected', description: \`Connected to ${address}\`, status: 'success', duration: 3000, isClosable: true, }); } catch (error) { console.error('Failed to connect wallet:', error); toast({ title: 'Connection failed', description: 'Failed to connect wallet. Please try again.', status: 'error', duration: 3000, isClosable: true, }); } } else { toast({ title: 'Metamask not detected', description: 'Please install Metamask to use this feature.', status: 'warning', duration: 3000, isClosable: true, }); } };
const performAction \= async (action) \=> { if (!walletConnected) { toast({ title: 'Wallet not connected', description: 'Please connect your wallet first.', status: 'warning', duration: 3000, isClosable: true, }); return; }
const provider \= new ethers.providers.Web3Provider(window.ethereum); const signer \= provider.getSigner(); const contract \= new ethers.Contract(forwarderAddress, forwarderABI, signer);
try { let tx; switch (action) { case 'connect': tx \= await contract.connectPool(poolAddress, "0x"); break; case 'disconnect': tx \= await contract.disconnectPool(poolAddress, "0x"); break; case 'claim': tx \= await contract.claimAll(poolAddress, memberAddress || account, "0x"); break; } await tx.wait(); toast({ title: 'Action successful', description: \`Successfully ${action}ed ${action \=== 'claim' ? 'from' : 'to'} pool\`, status: 'success', duration: 3000, isClosable: true, }); } catch (error) { console.error(\`Error ${action}ing:\`, error); toast({ title: 'Action failed', description: \`Failed to ${action} ${action \=== 'claim' ? 'from' : 'to'} pool. Please try again.\`, status: 'error', duration: 3000, isClosable: true, }); } };
return ( Pool Interaction Manager
{!walletConnected ? ( ) : ( Connected: {account} )}
setPoolAddress(e.target.value)} /> setMemberAddress(e.target.value)} />
);
}
Result
Loading...
This UI provides the following features:
1. **Wallet Connection**: Users can connect their Ethereum wallet to interact with the Superfluid protocol.
2. **Connect to Pool**: Users can connect to a specified pool.
3. **Disconnect from Pool**: Users can disconnect from a specified pool.
4. **Claim All Tokens**: Users can claim all available tokens from a specified pool.
5. **Feedback**: Toast notifications inform users about the success or failure of their actions.
To use this component:
1. Click "Connect Wallet" to connect your Ethereum wallet.
2. Enter the pool address in the "Pool Address" field.
3. (Optional) Enter a member address in the "Member Address" field for claiming. If left empty, it will use the connected wallet's address.
4. Click the appropriate button to connect to a pool, disconnect from a pool, or claim all tokens.
Remember to replace the `forwarderABI` placeholder with the actual ABI of the `GDAv1Forwarder` contract.
This example provides a starting point for building a user interface to interact with Superfluid pools. In a production environment, you would want to add more robust error checking, input validation, and additional features like displaying pool information or showing the user's current pool connections.
the example does not work on your developer environment?
The example above is a live example and requires the ABI to be imported. In the case of this example, the ABI has already been imported through the live coder.
In order to make it work on your developer environment, head to the [GDAv1Forwarder technical reference](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder)
and copy the ABI. Then, replace the `forwarderABI` variable in the example with the ABI you copied.
* [Interacting with the Superfluid Protocol](https://docs.superfluid.org/docs/sdk/distributions/connect-claim-pool#interacting-with-the-superfluid-protocol)
* [Contract ABI and Address](https://docs.superfluid.org/docs/sdk/distributions/connect-claim-pool#contract-abi-and-address)
* [Setting up with ethers.js](https://docs.superfluid.org/docs/sdk/distributions/connect-claim-pool#setting-up-with-ethersjs)
* [Understanding Connecting and Claiming](https://docs.superfluid.org/docs/sdk/distributions/connect-claim-pool#understanding-connecting-and-claiming)
* [Interacting with the GDAv1Forwarder Contract](https://docs.superfluid.org/docs/sdk/distributions/connect-claim-pool#interacting-with-the-gdav1forwarder-contract)
* [Connecting to a Pool](https://docs.superfluid.org/docs/sdk/distributions/connect-claim-pool#connecting-to-a-pool)
* [Disconnecting from a Pool](https://docs.superfluid.org/docs/sdk/distributions/connect-claim-pool#disconnecting-from-a-pool)
* [Claiming All Tokens from a Pool](https://docs.superfluid.org/docs/sdk/distributions/connect-claim-pool#claiming-all-tokens-from-a-pool)
* [Live UI Example for Pool Interaction](https://docs.superfluid.org/docs/sdk/distributions/connect-claim-pool#live-ui-example-for-pool-interaction)
---
# Staking Platform | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/protocol/examples/example2#__docusaurus_skipToContent_fallback)
On this page
This guide explores the development of a staking platform, leveraging the capabilities of Superfluid's [Distribution Pools](https://docs.superfluid.org/docs/protocol/distributions/guides/pools)
(also called the _General Distributions Agreement - GDA_).
Repository[](https://docs.superfluid.org/docs/protocol/examples/example2#repository "Direct link to Repository")
------------------------------------------------------------------------------------------------------------------
The contract and associated tests can be found in the [SuperfluidStaking Repository](https://github.com/superfluid-finance/sf-example-staking)
.
Contract Architecture[](https://docs.superfluid.org/docs/protocol/examples/example2#contract-architecture "Direct link to Contract Architecture")
---------------------------------------------------------------------------------------------------------------------------------------------------
The SuperfluidStaking system consists of two main contracts:
1. **SuperfluidStaking**: The core contract that manages staking, unstaking, and reward distribution.
2. **ClaimContract**: An auxiliary contract created for each staker to manage their individual rewards.
### SuperfluidStaking Contract[](https://docs.superfluid.org/docs/protocol/examples/example2#superfluidstaking-contract "Direct link to SuperfluidStaking Contract")
This contract is responsible for:
* Accepting stakes from users
* Managing the total staked amount
* Creating and upgrading Super Tokens for rewards
* Creating and managing a Superfluid pool for reward distribution
* Handling the unstaking process
* Facilitating reward claims
Key components:
* `underlyingStakedToken`: The ERC20 token that users stake
* `underlyingRewardsToken`: The ERC20 token used for rewards
* `superToken`: The Super Token wrapper for the rewards token
* `pool`: The Superfluid pool used for distributing rewards
* `scalingFactor`: A factor used to scale down staked amounts for precision
### ClaimContract[](https://docs.superfluid.org/docs/protocol/examples/example2#claimcontract "Direct link to ClaimContract")
This contract is created for each staker and is responsible for:
* Claiming rewards from the Superfluid pool
* Holding claimed rewards until withdrawn by the staker
Setup and Installation[](https://docs.superfluid.org/docs/protocol/examples/example2#setup-and-installation "Direct link to Setup and Installation")
------------------------------------------------------------------------------------------------------------------------------------------------------
To set up the development environment and run the tests, follow these steps:
1. **Install Foundry**
Foundry is a blazing fast, portable and modular toolkit for Ethereum application development. To install Foundry, run the following command:
curl -L https://foundry.paradigm.xyz | bash
Then, run `foundryup` in a new terminal session to install the latest version.
2. **Clone the repository**
git clone https://github.com/superfluid-finance/sf-example-stakingcd superfluid-staking
3. **Install dependencies**
Use Forge to install the necessary dependencies:
forge install
This will install OpenZeppelin contracts and Superfluid contracts as specified in the `foundry.toml` file.
4. **Compile the contracts**
forge build
5. **Run the tests**
forge test
This will run all the test cases defined in the `test` directory.
Contract Interaction Flow[](https://docs.superfluid.org/docs/protocol/examples/example2#contract-interaction-flow "Direct link to Contract Interaction Flow")
---------------------------------------------------------------------------------------------------------------------------------------------------------------
1. **Deployment**: The contract is deployed with parameters for the staked token, rewards token, Superfluid token factory, and scaling factor.
2. **Supplying Funds**: The contract owner calls `supplyFunds` to add rewards to the pool.
3. **Staking**: Users call `stake` to deposit tokens. This creates a ClaimContract if they don't have one and updates their units in the Superfluid pool.
4. **Unstaking**: Users call `unstake` to withdraw their staked tokens. This updates their units in the Superfluid pool.
5. **Claiming Rewards**: Users call `claimRewards` to receive their accumulated rewards. This interacts with their ClaimContract to fetch and distribute rewards.
Key Considerations[](https://docs.superfluid.org/docs/protocol/examples/example2#key-considerations "Direct link to Key Considerations")
------------------------------------------------------------------------------------------------------------------------------------------
* The use of a scaling factor is crucial for maintaining precision in reward calculations, especially when dealing with tokens of different decimals.
* The ClaimContract pattern allows for efficient reward claiming without requiring frequent updates to the main contract.
* The contract leverages Superfluid's streaming capabilities for continuous and gas-efficient reward distribution.
Testing[](https://docs.superfluid.org/docs/protocol/examples/example2#testing "Direct link to Testing")
---------------------------------------------------------------------------------------------------------
The test suite (located in `test/SuperfluidStaking.t.sol`) covers various scenarios including:
* Staking and unstaking
* Reward distribution and claiming
* Multiple users interacting with the contract
* Edge cases and potential vulnerabilities
To run a specific test:
forge test --match-test testFunctionName
Replace `testFunctionName` with the name of the test function you want to run.
Conclusion[](https://docs.superfluid.org/docs/protocol/examples/example2#conclusion "Direct link to Conclusion")
------------------------------------------------------------------------------------------------------------------
The SuperfluidStaking contract provides a robust and efficient system for stake-based reward distribution using Superfluid. By following this guide, you should be able to understand the contract's architecture, set up your development environment, and run the tests.
* [Repository](https://docs.superfluid.org/docs/protocol/examples/example2#repository)
* [Contract Architecture](https://docs.superfluid.org/docs/protocol/examples/example2#contract-architecture)
* [SuperfluidStaking Contract](https://docs.superfluid.org/docs/protocol/examples/example2#superfluidstaking-contract)
* [ClaimContract](https://docs.superfluid.org/docs/protocol/examples/example2#claimcontract)
* [Setup and Installation](https://docs.superfluid.org/docs/protocol/examples/example2#setup-and-installation)
* [Contract Interaction Flow](https://docs.superfluid.org/docs/protocol/examples/example2#contract-interaction-flow)
* [Key Considerations](https://docs.superfluid.org/docs/protocol/examples/example2#key-considerations)
* [Testing](https://docs.superfluid.org/docs/protocol/examples/example2#testing)
* [Conclusion](https://docs.superfluid.org/docs/protocol/examples/example2#conclusion)
---
# Rewards Distribution Using Macros | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/sdk/examples/example1#__docusaurus_skipToContent_fallback)
On this page
This guide will walk you through creating a web application that enables streaming reward distributions using Superfluid's [Distribution Pools](https://docs.superfluid.org/docs/protocol/distributions/overview)
and Macro for [Batching Calls](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls)
.
tip
If you want to see the full example, you can check it out in the [GitHub Repository](https://github.com/superfluid-finance/rewards-macro-example)
.
Overview[](https://docs.superfluid.org/docs/sdk/examples/example1#overview "Direct link to Overview")
-------------------------------------------------------------------------------------------------------
The application we'll build allows users to:
* Connect their wallet and validate network
* Select a Superfluid pool
* Add multiple recipients with their respective units
* Set a flow rate for rewards
* Execute all operations in a single transaction
Prerequisites[](https://docs.superfluid.org/docs/sdk/examples/example1#prerequisites "Direct link to Prerequisites")
----------------------------------------------------------------------------------------------------------------------
Before starting, ensure you have:
* Basic knowledge of React and TypeScript
* Node.js installed
* A Web3 wallet (like MetaMask)
* Some ETH on Optimism Sepolia network
Setting Up the Project[](https://docs.superfluid.org/docs/sdk/examples/example1#setting-up-the-project "Direct link to Setting Up the Project")
-------------------------------------------------------------------------------------------------------------------------------------------------
1. Create a new Next.js project:
npx create-next-app@latest rewards-distribution --typescript --tailwindcd rewards-distribution
2. Install dependencies:
npm install ethers@6 @superfluid-finance/sdk-core
3. Install UI components:
npx shadcn-ui@latest init
Understanding the Core Concepts[](https://docs.superfluid.org/docs/sdk/examples/example1#understanding-the-core-concepts "Direct link to Understanding the Core Concepts")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
### Superfluid Distribution Pools[](https://docs.superfluid.org/docs/sdk/examples/example1#superfluid-distribution-pools "Direct link to Superfluid Distribution Pools")
[Distribution Pools](https://docs.superfluid.org/docs/protocol/distributions/overview)
allow for proportional distribution of streaming tokens. Think of it as a smart contract that:
* Manages a pool of tokens
* Distributes streams based on units assigned to recipients
* Handles all the complex token streaming logic
tip
To deploy a Distribution Pool, you can use the [GDAv1Forwarder](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder)
.
### Superfluid Macros[](https://docs.superfluid.org/docs/sdk/examples/example1#superfluid-macros "Direct link to Superfluid Macros")
[Macros](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls)
allow us to batch multiple operations into a single transaction. In our case, we're using:
* `MacroForwarder`: Contract that executes our macro
* [`RewardsMacro`](https://github.com/superfluid-finance/rewards-macro-example/blob/main/contracts/RewardsMacro.sol)
: Our custom macro for setting up distributions
In our example, we deployed a [`RewardsMacro`](https://github.com/superfluid-finance/rewards-macro-example/blob/main/contracts/RewardsMacro.sol)
contract on [OP Sepolia](https://optimism-sepolia.blockscout.com/address/0xA315e7EB0a278fac7B3a74DB895f5bf801EAb632?tab=contract)
for the purposes of our example.
Key Components[](https://docs.superfluid.org/docs/sdk/examples/example1#key-components "Direct link to Key Components")
-------------------------------------------------------------------------------------------------------------------------
### 1\. Network Management[](https://docs.superfluid.org/docs/sdk/examples/example1#1-network-management "Direct link to 1. Network Management")
First, we need to ensure users are on the correct network:
const OP_SEPOLIA_CHAIN_ID = "0xaa37dc" // 11155420 in hexconst switchToOpSepolia = async () => { try { await window.ethereum.request({ method: 'wallet_switchEthereumChain', params: [{ chainId: OP_SEPOLIA_CHAIN_ID }], }); return true; } catch (switchError) { // Handle network switch error }}
### 2\. Pool Validation[](https://docs.superfluid.org/docs/sdk/examples/example1#2-pool-validation "Direct link to 2. Pool Validation")
We validate the pool address and check user's balance:
const POOL_ABI = ["function superToken() external view returns (ISuperfluidToken)"]const SUPER_TOKEN_ABI = ["function balanceOf(address account) external view returns (uint256)"]const checkPoolAndBalance = async () => { const poolContract = new ethers.Contract(poolAddress, POOL_ABI, provider); const tokenAddress = await poolContract.superToken(); const tokenContract = new ethers.Contract(tokenAddress, SUPER_TOKEN_ABI, provider); const balance = await tokenContract.balanceOf(userAddress); // Handle results}
### 3\. Reward Distribution Setup[](https://docs.superfluid.org/docs/sdk/examples/example1#3-reward-distribution-setup "Direct link to 3. Reward Distribution Setup")
The core functionality uses the RewardsMacro contract:
const executeRewardsMacro = async () => { // Parse recipients and units const receivers = [...] // Array of addresses const units = [...] // Array of BigInts // Convert flow rate from tokens/day to wei/second const weiBigInt = ethers.parseEther(flowRatePerDay) const flowRateWeiPerSecond = weiBigInt / BigInt(86400) // Get macro parameters const params = await rewardsMacro.getParams( poolAddress, receivers, units, flowRateWeiPerSecond ) // Execute through MacroForwarder await macroForwarder.runMacro(REWARDS_MACRO, params)}
User Interface[](https://docs.superfluid.org/docs/sdk/examples/example1#user-interface "Direct link to User Interface")
-------------------------------------------------------------------------------------------------------------------------

_Screenshot of the UI_
The UI is built with Tailwind CSS and shadcn/ui components. Key features include:
* Network status indicator
* Pool validation feedback
* Balance display
* Recipients input area
* Flow rate input with conversion
Reward Stream Distribution {/* Network Check */} {/* Pool Input */} {/* Recipients Input */} {/* Flow Rate Input */} {/* Execute Button */}
Testing the Application[](https://docs.superfluid.org/docs/sdk/examples/example1#testing-the-application "Direct link to Testing the Application")
----------------------------------------------------------------------------------------------------------------------------------------------------
1. Deploy the contract and set up your pool
* Deploy the `RewardsMacro` contract on your desired network (you can use the contract deployed on [OP Sepolia](https://optimism-sepolia.blockscout.com/address/0xA315e7EB0a278fac7B3a74DB895f5bf801EAb632?tab=contract)
)
* Create your pool using the [GDAv1Forwarder](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder)
* Ensure you use the correct Super Token for your pool (in our example, we used the [Super fake DAI](https://optimism-sepolia.blockscout.com/address/0x7f5c765057ef45c28ae624f7b77854c32c201422?tab=contract)
Super Token)
2. Test the flow:
* Connect wallet
* Enter pool address
* Add recipients
* Set flow rate
* Execute distribution
Common Issues and Solutions[](https://docs.superfluid.org/docs/sdk/examples/example1#common-issues-and-solutions "Direct link to Common Issues and Solutions")
----------------------------------------------------------------------------------------------------------------------------------------------------------------
### Invalid Pool Address[](https://docs.superfluid.org/docs/sdk/examples/example1#invalid-pool-address "Direct link to Invalid Pool Address")
try { await poolContract.superToken()} catch (e) { // Handle invalid pool}
### Insufficient Balance[](https://docs.superfluid.org/docs/sdk/examples/example1#insufficient-balance "Direct link to Insufficient Balance")
if (Number(userBalance) === 0) { // Disable execution // Show warning}
### Network Issues[](https://docs.superfluid.org/docs/sdk/examples/example1#network-issues "Direct link to Network Issues")
if (chainId !== OP_SEPOLIA_CHAIN_ID) { await switchToOpSepolia()}
Next Steps[](https://docs.superfluid.org/docs/sdk/examples/example1#next-steps "Direct link to Next Steps")
-------------------------------------------------------------------------------------------------------------
Consider extending the application with:
* Multiple network support
* Distribution history
* Analytics dashboard
* [Overview](https://docs.superfluid.org/docs/sdk/examples/example1#overview)
* [Prerequisites](https://docs.superfluid.org/docs/sdk/examples/example1#prerequisites)
* [Setting Up the Project](https://docs.superfluid.org/docs/sdk/examples/example1#setting-up-the-project)
* [Understanding the Core Concepts](https://docs.superfluid.org/docs/sdk/examples/example1#understanding-the-core-concepts)
* [Superfluid Distribution Pools](https://docs.superfluid.org/docs/sdk/examples/example1#superfluid-distribution-pools)
* [Superfluid Macros](https://docs.superfluid.org/docs/sdk/examples/example1#superfluid-macros)
* [Key Components](https://docs.superfluid.org/docs/sdk/examples/example1#key-components)
* [1\. Network Management](https://docs.superfluid.org/docs/sdk/examples/example1#1-network-management)
* [2\. Pool Validation](https://docs.superfluid.org/docs/sdk/examples/example1#2-pool-validation)
* [3\. Reward Distribution Setup](https://docs.superfluid.org/docs/sdk/examples/example1#3-reward-distribution-setup)
* [User Interface](https://docs.superfluid.org/docs/sdk/examples/example1#user-interface)
* [Testing the Application](https://docs.superfluid.org/docs/sdk/examples/example1#testing-the-application)
* [Common Issues and Solutions](https://docs.superfluid.org/docs/sdk/examples/example1#common-issues-and-solutions)
* [Invalid Pool Address](https://docs.superfluid.org/docs/sdk/examples/example1#invalid-pool-address)
* [Insufficient Balance](https://docs.superfluid.org/docs/sdk/examples/example1#insufficient-balance)
* [Network Issues](https://docs.superfluid.org/docs/sdk/examples/example1#network-issues)
* [Next Steps](https://docs.superfluid.org/docs/sdk/examples/example1#next-steps)
---
# Bounty Program | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/protocol/contribute/bounty-program#__docusaurus_skipToContent_fallback)
On this page
The Superfluid Bounty Program allows developers to tackle a variety of technical issues laid out by the Superfluid Team and earn payouts for completion. Ready to get bounty hunting? Let's get started!
Bounties[](https://docs.superfluid.org/docs/protocol/contribute/bounty-program#bounties "Direct link to Bounties")
--------------------------------------------------------------------------------------------------------------------
Pick a bounty issue you would like to complete in our [repo](https://github.com/orgs/superfluid-finance/projects/17/)
. They range in skill utilization (Solidity, Node.js, DevOps, etc.) and size.
Getting Started[](https://docs.superfluid.org/docs/protocol/contribute/bounty-program#getting-started "Direct link to Getting Started")
-----------------------------------------------------------------------------------------------------------------------------------------
Comment on the GitHub issue with the below template:
Hi @youssea, I'm interested in taking on this bounty: Expected Completion Date: [ date you intend on completing the bounty by ** ]
In the #💰bounties channel in our [Discord](https://discord.gg/pPzPEDMVua)
, notify us of your intent to create the bounty with the below message template:
Hi @Sunny | Superfluid#7782, I'm interested in taking on this bounty: Issue: [ link to GitHub issue ] Expected Completion Date: [ date you intend on completing the bounty by ** ]
\*\* This is a soft deadline. It is simply so we can check up on progress and offer support.
During Work[](https://docs.superfluid.org/docs/protocol/contribute/bounty-program#during-work "Direct link to During Work")
-----------------------------------------------------------------------------------------------------------------------------
A Superfluid team member will open a Discord thread for communication as you work on your issue. Let us know how things are going and if you've got any questions! We're super responsive :)
Upon Completion[](https://docs.superfluid.org/docs/protocol/contribute/bounty-program#upon-completion "Direct link to Upon Completion")
-----------------------------------------------------------------------------------------------------------------------------------------
* Submit a pull request and tag the bounty issue you've completed in it ([Example Pull Request](https://github.com/superfluid-finance/protocol-monorepo/pull/717)
).
* Once it's merged, fill out [this form](https://docs.google.com/forms/d/e/1FAIpQLSePPMtMcDndvgJvpkDMtY1BChkrXaqABO0SKA-4c-i2rbhZKA/viewform)
and submit [this invoice](https://app.request.finance/create/3834fe3c2faaa829)
to us.
* In the Bounty KYC Form, for "Hackathon Name" put down the "Bounty".
* In the Bounty KYC Form, for "Your Hack Name" put down the title of your bounty.
* In the Request Invoice, please invoice for USDC on Polygon (not DAI or any other token).
* Wait for your bounty to pay out on the next Wednesday! Congrats on your valued contribution to Superfluid 🏁
Referrals[](https://docs.superfluid.org/docs/protocol/contribute/bounty-program#referrals "Direct link to Referrals")
-----------------------------------------------------------------------------------------------------------------------
If you find someone to complete a bounty, you can earn 20% of the bounty value as a referral payout!
* When the person you referred completes the bounty, let us know in the **#💰bounties** channel that you referred that person.
* We will verify with the bounty completer that you did in fact refer that person.
* If that looks good, we'll give you the green light to follow steps 2 and 3 of "Upon Completion" below to earn your payout.
Note
To make it easier for us to verify your referral, please have the person you referred add this to the form field _Your Hack Name_: "Referred by \[your Discord or GitHub handle\]".
Important Note[](https://docs.superfluid.org/docs/protocol/contribute/bounty-program#important-note "Direct link to Important Note")
--------------------------------------------------------------------------------------------------------------------------------------
Bounty hunters must adhere to the following statement 👇
_"I am not a resident, citizen, national or agent of, or an entity organized, incorporated or doing business in, Belarus, Burundi, Crimea and Sevastopol, Cuba, Democratic Republic of Congo, Iran, Iraq, Libya, North Korea, Somalia, Sudan, Syria, Venezuela, Zimbabwe or any other country to which the United States, the United Kingdom, the Cayman Islands, the European Union or any of its member states or the United Nations or any of its member states (collectively, the “Major Jurisdictions”) embargoes goods or imposes similar sanctions (such embargoed or sanctioned territories, collectively, the “Restricted Territories”). I am not, and do not directly or indirectly own or control, and have not received any assets from, any blockchain address that is, listed on any sanctions list or equivalent maintained by any of the Major Jurisdictions (such sanctions-listed persons, collectively, “Sanctions Lists Persons”). I do not intend to transact in or with any Restricted Territories or Sanctions List Persons. I did not take part and do not intend to take part to any illegal activity, including but not limited to money laundering, internet hacking and terrorism financing."_
* [Bounties](https://docs.superfluid.org/docs/protocol/contribute/bounty-program#bounties)
* [Getting Started](https://docs.superfluid.org/docs/protocol/contribute/bounty-program#getting-started)
* [During Work](https://docs.superfluid.org/docs/protocol/contribute/bounty-program#during-work)
* [Upon Completion](https://docs.superfluid.org/docs/protocol/contribute/bounty-program#upon-completion)
* [Referrals](https://docs.superfluid.org/docs/protocol/contribute/bounty-program#referrals)
* [Important Note](https://docs.superfluid.org/docs/protocol/contribute/bounty-program#important-note)
---
# Batch Calls with Host Contract | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#__docusaurus_skipToContent_fallback)
On this page
Execute multiple Superfluid operations in a single transaction using the Host contract's `batchCall` function. This approach provides direct control over batch operations without requiring custom macro contracts, leveraging the [modular architecture](https://docs.superfluid.org/docs/technical-reference/Architecture)
of Superfluid, and specifically the mastermind contract of the protocol called the [Superfluid Host](https://docs.superfluid.org/docs/concepts/advanced-topics/superfluid-host)
.
Background[](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#background "Direct link to Background")
---------------------------------------------------------------------------------------------------------------------------------
The Superfluid Host contract makes it possible to batch transactions from day one through a method called `batchCall`. This direct approach allows you to combine multiple Superfluid operations into a single atomic transaction, providing gas optimization and ensuring all operations succeed or fail together.
Unlike the [MacroForwarder approach](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-macro)
, this method gives you direct control over the operations without needing to deploy custom contracts.
How Batch Calls Work[](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#how-batch-calls-work "Direct link to How Batch Calls Work")
---------------------------------------------------------------------------------------------------------------------------------------------------------------
Batch calls work by constructing an array of `ISuperfluid.Operation` structs and passing them to the Host contract's `batchCall` function. Each operation contains:
* **operationType**: Identifies the type of operation (e.g., token upgrade, flow creation)
* **target**: The contract address to call
* **data**: Encoded function call data
struct Operation { uint32 operationType; address target; bytes data;}
Operation Types[](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#operation-types "Direct link to Operation Types")
------------------------------------------------------------------------------------------------------------------------------------------------
Each operation in a batch call requires an operation type identifier. These are defined in the `BatchOperation` library in [Definitions.sol](https://github.com/superfluid-org/protocol-monorepo/blob/dev/packages/ethereum-contracts/contracts/interfaces/superfluid/Definitions.sol)
:
// Available operation types:OPERATION_TYPE.UNSUPPORTED // = 0OPERATION_TYPE.ERC20_APPROVE // = 1OPERATION_TYPE.ERC20_TRANSFER_FROM // = 2OPERATION_TYPE.ERC777_SEND // = 3 (deprecated)OPERATION_TYPE.ERC20_INCREASE_ALLOWANCE // = 4OPERATION_TYPE.ERC20_DECREASE_ALLOWANCE // = 5OPERATION_TYPE.SUPERTOKEN_UPGRADE // = 101OPERATION_TYPE.SUPERTOKEN_DOWNGRADE // = 102OPERATION_TYPE.SUPERFLUID_CALL_AGREEMENT // = 201 (main type for CFA/GDA calls)OPERATION_TYPE.CALL_APP_ACTION // = 202OPERATION_TYPE.SIMPLE_FORWARD_CALL // = 301OPERATION_TYPE.ERC2771_FORWARD_CALL // = 302
Contract Addresses and ABIs[](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#contract-addresses-and-abis "Direct link to Contract Addresses and ABIs")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
You can find contract addresses for all networks on the [Superfluid Explorer](https://explorer.superfluid.org/)
. For example, Base Sepolia contracts can be found at: [https://explorer.superfluid.org/base-sepolia/protocol](https://explorer.superfluid.org/base-sepolia/protocol)
### Superfluid Host Contract[](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#superfluid-host-contract "Direct link to Superfluid Host Contract")
The Host contract is the central contract that executes batch calls. Here's the Base Sepolia example:
**Contract Address (Base Sepolia):**
const hostAddress = "0x109412E3C84f0539b43d39dB691B08c90f58dC7c";
**Host ABI (Essential Functions):**
[ { "inputs": [ { "components": [ { "internalType": "uint32", "name": "operationType", "type": "uint32" }, { "internalType": "address", "name": "target", "type": "address" }, { "internalType": "bytes", "name": "data", "type": "bytes" } ], "internalType": "struct ISuperfluid.Operation[]", "name": "operations", "type": "tuple[]" } ], "name": "batchCall", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "components": [ { "internalType": "uint32", "name": "operationType", "type": "uint32" }, { "internalType": "address", "name": "target", "type": "address" }, { "internalType": "bytes", "name": "data", "type": "bytes" } ], "internalType": "struct ISuperfluid.Operation[]", "name": "operations", "type": "tuple[]" } ], "name": "forwardBatchCall", "outputs": [], "stateMutability": "nonpayable", "type": "function" }]
### CFA Forwarder Contract[](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#cfa-forwarder-contract "Direct link to CFA Forwarder Contract")
For flow operations (create, update, delete flows):
**Contract Address (Base Sepolia):**
const cfaForwarderAddress = "0xcfA132E353cB4E398080B9700609bb008eceB125";
**CFA Forwarder ABI (Essential Functions):**
[ { "inputs": [ { "internalType": "contract ISuperToken", "name": "token", "type": "address" }, { "internalType": "address", "name": "sender", "type": "address" }, { "internalType": "address", "name": "receiver", "type": "address" }, { "internalType": "int96", "name": "flowRate", "type": "int96" }, { "internalType": "bytes", "name": "userData", "type": "bytes" } ], "name": "createFlow", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "contract ISuperToken", "name": "token", "type": "address" }, { "internalType": "address", "name": "sender", "type": "address" }, { "internalType": "address", "name": "receiver", "type": "address" }, { "internalType": "int96", "name": "flowRate", "type": "int96" }, { "internalType": "bytes", "name": "userData", "type": "bytes" } ], "name": "updateFlow", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "contract ISuperToken", "name": "token", "type": "address" }, { "internalType": "address", "name": "sender", "type": "address" }, { "internalType": "address", "name": "receiver", "type": "address" }, { "internalType": "bytes", "name": "userData", "type": "bytes" } ], "name": "deleteFlow", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "nonpayable", "type": "function" }]
### GDA Forwarder Contract[](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#gda-forwarder-contract "Direct link to GDA Forwarder Contract")
For distribution operations (create pools, distribute tokens):
**Contract Address (Base Sepolia):**
const gdaForwarderAddress = "0x6DA13Bde224A05a288748d857b9e7DDEffd1dE08";
**GDA Forwarder ABI (Essential Functions):**
[ { "inputs": [ { "internalType": "contract ISuperToken", "name": "token", "type": "address" }, { "internalType": "address", "name": "admin", "type": "address" }, { "components": [ { "internalType": "bool", "name": "transferabilityForUnitsOwner", "type": "bool" }, { "internalType": "bool", "name": "distributionFromAnyAddress", "type": "bool" } ], "internalType": "struct PoolConfig", "name": "config", "type": "tuple" } ], "name": "createPool", "outputs": [ { "internalType": "bool", "name": "success", "type": "bool" }, { "internalType": "contract ISuperfluidPool", "name": "pool", "type": "address" } ], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "contract ISuperToken", "name": "token", "type": "address" }, { "internalType": "address", "name": "from", "type": "address" }, { "internalType": "contract ISuperfluidPool", "name": "pool", "type": "address" }, { "internalType": "uint256", "name": "requestedAmount", "type": "uint256" }, { "internalType": "bytes", "name": "userData", "type": "bytes" } ], "name": "distribute", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "contract ISuperToken", "name": "token", "type": "address" }, { "internalType": "address", "name": "from", "type": "address" }, { "internalType": "contract ISuperfluidPool", "name": "pool", "type": "address" }, { "internalType": "int96", "name": "requestedFlowRate", "type": "int96" }, { "internalType": "bytes", "name": "userData", "type": "bytes" } ], "name": "distributeFlow", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [ { "internalType": "contract ISuperfluidPool", "name": "pool", "type": "address" }, { "internalType": "address", "name": "memberAddress", "type": "address" }, { "internalType": "uint128", "name": "newUnits", "type": "uint128" }, { "internalType": "bytes", "name": "userData", "type": "bytes" } ], "name": "updateMemberUnits", "outputs": [{ "internalType": "bool", "name": "", "type": "bool" }], "stateMutability": "nonpayable", "type": "function" }]
Contract Addresses
These are the Base Sepolia testnet addresses. For other networks, visit the [Superfluid Explorer](https://explorer.superfluid.org/)
and select your desired network.
Basic Implementation[](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#basic-implementation "Direct link to Basic Implementation")
---------------------------------------------------------------------------------------------------------------------------------------------------------------
### Using the SDK with React Hooks[](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#using-the-sdk-with-react-hooks "Direct link to Using the SDK with React Hooks")
Here's how to create a batch call using the Superfluid SDK:
import React, { useState } from 'react';import { ethers } from 'ethers';import { hostAbi, hostAddress, superTokenAbi, cfaForwarderAbi, cfaForwarderAddress } from '@superfluid-finance/sdk-core';import { useAccount, useWriteContract } from 'wagmi';function BatchCallComponent() { const { address } = useAccount(); const [superToken, setSuperToken] = useState(''); const [receiver, setReceiver] = useState(''); const [amount, setAmount] = useState(''); const [flowRate, setFlowRate] = useState(''); const { writeContract: batchCall } = useWriteContract(); const executeBatchCall = async () => { if (!address) return; // Define operations const operations = [ // Operation 1: Upgrade tokens { operationType: 101, // SUPERTOKEN_UPGRADE target: superToken, data: ethers.utils.defaultAbiCoder.encode( ['uint256'], [ethers.utils.parseEther(amount)] ) }, // Operation 2: Create flow { operationType: 201, // SUPERFLUID_CALL_AGREEMENT target: "0xcfA132E353cB4E398080B9700609bb008eceB125", // Base Sepolia CFA Forwarder data: ethers.utils.defaultAbiCoder.encode( ['bytes', 'bytes'], [ ethers.utils.defaultAbiCoder.encode( ['address', 'address', 'address', 'int96', 'bytes'], [superToken, address, receiver, flowRate, '0x'] ), '0x' ] ) } ]; // Execute batch call batchCall({ address: "0x109412E3C84f0539b43d39dB691B08c90f58dC7c", // Base Sepolia Host abi: hostAbi, functionName: 'batchCall', args: [operations] }); }; return (
);
}
Result
Loading...
Error Handling and Best Practices[](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#error-handling-and-best-practices "Direct link to Error Handling and Best Practices")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
### Atomic Execution[](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#atomic-execution "Direct link to Atomic Execution")
Batch calls are atomic - if any operation fails, the entire batch reverts:
try { const tx = await hostContract.batchCall(operations); await tx.wait(); console.log('All operations succeeded');} catch (error) { console.error('Batch call failed:', error); // All operations have been reverted}
### Operation Ordering[](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#operation-ordering "Direct link to Operation Ordering")
Operations execute sequentially, so order matters:
// ✅ Good: Approve first, then upgradeconst operations = [ approveOperation, upgradeOperation, createFlowOperation];// ❌ Bad: Trying to upgrade without approvalconst operations = [ upgradeOperation, // This will fail approveOperation];
### Conditional Operations[](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#conditional-operations "Direct link to Conditional Operations")
You can build conditional batch calls based on current state:
async function buildConditionalBatch(tokenAddress, userAddress) { const operations = []; // Check current balance const balance = await superToken.balanceOf(userAddress); if (balance.lt(ethers.utils.parseEther('100'))) { // Add upgrade operation if balance is low operations.push({ operationType: 101, target: tokenAddress, data: ethers.utils.defaultAbiCoder.encode( ['uint256'], [ethers.utils.parseEther('1000')] ) }); } // Always add flow creation operations.push(createFlowOperation); return operations;}
Comparison with MacroForwarder[](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#comparison-with-macroforwarder "Direct link to Comparison with MacroForwarder")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| Feature | Host batchCall | MacroForwarder |
| --- | --- | --- |
| **Deployment** | No deployment needed | Requires macro contract |
| **Flexibility** | Full control over operations | Predefined macro logic |
| **Gas Cost** | Lower (direct calls) | Slightly higher (proxy) |
| **Reusability** | Manual construction | Reusable macro functions |
| **Complexity** | Higher implementation | Simpler usage |
Next Steps[](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#next-steps "Direct link to Next Steps")
---------------------------------------------------------------------------------------------------------------------------------
* Explore the [MacroForwarder approach](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-macro)
for reusable patterns
* Learn about [Advanced Topics](https://docs.superfluid.org/docs/sdk/advanced-topics/)
in the SDK
* Check out [automation contracts](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/)
for scheduled operations
Related Resources[](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#related-resources "Direct link to Related Resources")
------------------------------------------------------------------------------------------------------------------------------------------------------
* [Superfluid Host Contract](https://docs.superfluid.org/docs/concepts/advanced-topics/superfluid-host)
* [CFA Forwarder Reference](https://docs.superfluid.org/docs/technical-reference/CFAv1Forwarder)
* [GDA Forwarder Reference](https://docs.superfluid.org/docs/technical-reference/GDAv1Forwarder)
* [SDK Core Documentation](https://sdk.superfluid.pro/)
* [Background](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#background)
* [How Batch Calls Work](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#how-batch-calls-work)
* [Operation Types](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#operation-types)
* [Contract Addresses and ABIs](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#contract-addresses-and-abis)
* [Superfluid Host Contract](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#superfluid-host-contract)
* [CFA Forwarder Contract](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#cfa-forwarder-contract)
* [GDA Forwarder Contract](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#gda-forwarder-contract)
* [Basic Implementation](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#basic-implementation)
* [Using the SDK with React Hooks](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#using-the-sdk-with-react-hooks)
* [Using Ethers.js Directly](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#using-ethersjs-directly)
* [Common Batch Call Patterns](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#common-batch-call-patterns)
* [1\. Wrap and Stream Pattern](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#1-wrap-and-stream-pattern)
* [2\. Multi-Flow Management](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#2-multi-flow-management)
* [3\. Pool Distribution Batch](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#3-pool-distribution-batch)
* [Complete Example: Batch Flow Manager](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#complete-example-batch-flow-manager)
* [Error Handling and Best Practices](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#error-handling-and-best-practices)
* [Atomic Execution](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#atomic-execution)
* [Operation Ordering](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#operation-ordering)
* [Conditional Operations](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#conditional-operations)
* [Comparison with MacroForwarder](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#comparison-with-macroforwarder)
* [Next Steps](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#next-steps)
* [Related Resources](https://docs.superfluid.org/docs/sdk/advanced-topics/batch-calls-forwarder#related-resources)
---
# Subgraph | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/sdk/distributions/subgraph#__docusaurus_skipToContent_fallback)
On this page
The Graph is the indexing layer of our industry, providing a queryable platform for the vast data produced by blockchain networks. The Graph can be used for querying data in the Superfluid ecosystem and other on-chain data. Experiment with queries using the [GraphQL Playground](https://thegraph.com/hosted-service/)
.
New to GraphQL?
Before diving into subgraph queries, familiarize yourself with GraphQL basics: [Learn GraphQL](https://graphql.org/learn/)
Querying Different Networks[](https://docs.superfluid.org/docs/sdk/distributions/subgraph#querying-different-networks "Direct link to Querying Different Networks")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
### Superfluid Explorer[](https://docs.superfluid.org/docs/sdk/distributions/subgraph#superfluid-explorer "Direct link to Superfluid Explorer")
The Superfluid Explorer is an interactive interface for exploring the Superfluid Protocol and interacting with its Subgraph. It provides an intuitive way to query on-chain data, get contract addresses, and manage your Superfluid finances. The console supports various blockchain networks, allowing you to seamlessly switch between them and access specific data sets. Whether you're analyzing streams, checking balances, or staying up to date with the new deployments. The Superfluid Explorer makes these tasks accessible and straightforward.
Explore Superfluid data across various networks using the Superfluid Explorer. Select a network to start querying:
* Popular
* Other
[Ethereum](https://console.superfluid.finance/subgraph?_network=ethereum)
[Polygon](https://console.superfluid.finance/subgraph?_network=matic)
[Avalanche](https://console.superfluid.finance/subgraph?_network=avalanche)
[Optimism](https://console.superfluid.finance/subgraph?_network=optimism)
[Arbitrum](https://console.superfluid.finance/subgraph?_network=arbitrum)
[Binance Smart Chain](https://console.superfluid.finance/subgraph?_network=binance-smart-chain)
For other networks, use the Superfluid Explorer:
[Superfluid Explorer](https://console.superfluid.finance/)
### Subgraph Networks[](https://docs.superfluid.org/docs/sdk/distributions/subgraph#subgraph-networks "Direct link to Subgraph Networks")
You can have the full list of available subgraph endpoints in the [Subgraph Endpoints](https://docs.superfluid.org/docs/technical-reference/subgraph)
page.
Resources[](https://docs.superfluid.org/docs/sdk/distributions/subgraph#resources "Direct link to Resources")
---------------------------------------------------------------------------------------------------------------
* **Subgraph Queries**: [Guide on Querying the Graph](https://thegraph.com/docs/en/developer/query-the-graph/)
* **Deploy a Subgraph**: [Creating a Subgraph](https://thegraph.com/docs/en/developer/create-subgraph-hosted/)
* **GraphQL Schema**: [Superfluid Schema](https://github.com/superfluid-finance/protocol-monorepo/blob/dev/packages/subgraph/schema.graphql)
* **Our Subgraph Endpoints**: [Subgraph Endpoints](https://docs.superfluid.org/docs/technical-reference/subgraph)
Helpful Tips[](https://docs.superfluid.org/docs/sdk/distributions/subgraph#helpful-tips "Direct link to Helpful Tips")
------------------------------------------------------------------------------------------------------------------------
* All addresses in the subgraph (`id`, `underlyingAddress`, etc.) are lowercase.
* Convert addresses to lowercase before querying.
### Notable Breaking Changes[](https://docs.superfluid.org/docs/sdk/distributions/subgraph#notable-breaking-changes "Direct link to Notable Breaking Changes")
Migrating From Legacy Subgraph to V1
Significant changes were made in October 2021:
* `totalSubscriptions` is now `totalSubscriptionsWithUnits`.
* `Subscriber` entity changed to `Subscription`.
* `createdAt` and `updatedAt` fields are now `createdAtTimestamp` and `updatedAtTimestamp`.
Schema Overview[](https://docs.superfluid.org/docs/sdk/distributions/subgraph#schema-overview "Direct link to Schema Overview")
---------------------------------------------------------------------------------------------------------------------------------
The Superfluid Subgraph includes various entities for querying. Think of entities as analogous to database tables. Here's a brief overview:
### Event Entities[](https://docs.superfluid.org/docs/sdk/distributions/subgraph#event-entities "Direct link to Event Entities")
Event entities correspond to contract events, often with added data. Each event entity is immutable and created once.
* **Event ID Format**: `eventName-transactionHash-logIndex`.
* **Naming Convention**: For V1, event names end with 'Event'.
### Higher Order Level Entities (HOL)[](https://docs.superfluid.org/docs/sdk/distributions/subgraph#higher-order-level-entities-hol "Direct link to Higher Order Level Entities (HOL)")
HOL entities represent entities over their lifetime and may be updated.
* **`Account`**: Represents any address interacting with Superfluid.
* **`Token`**: Represents valid SuperTokens.
* **`Pool`**, **`PoolMember`**, **`Stream`**, **`StreamPeriod`**: Related to Superfluid streams and [pools](https://docs.superfluid.org/docs/protocol/distributions/guides/pools)
.
### Aggregate Entities[](https://docs.superfluid.org/docs/sdk/distributions/subgraph#aggregate-entities "Direct link to Aggregate Entities")
Aggregate entities store cumulative data at both account-token and global token levels:
* **`TokenStatistic`**: Aggregates data for a single Token type.
* **`AccountTokenSnapshot`**: Aggregates data on an account's interaction with a token.
Query Examples[](https://docs.superfluid.org/docs/sdk/distributions/subgraph#query-examples "Direct link to Query Examples")
------------------------------------------------------------------------------------------------------------------------------
### Super Token Data Query[](https://docs.superfluid.org/docs/sdk/distributions/subgraph#super-token-data-query "Direct link to Super Token Data Query")
{ tokens(first: 100) { id symbol name underlyingAddress }}
### Get the pools that a user is a member of[](https://docs.superfluid.org/docs/sdk/distributions/subgraph#get-the-pools-that-a-user-is-a-member-of "Direct link to Get the pools that a user is a member of")
To list all pools that an account is currently a member (insert the ethereum address in the query below):
query MyQuery { pools( first: 10 where: {poolMembers_: {account: "YOUR_ADDRESS_HERE", account_: {}}} ) { totalUnits totalMembers flowRate createdAtBlockNumber }}
### Get all the pools for a specific token[](https://docs.superfluid.org/docs/sdk/distributions/subgraph#get-all-the-pools-for-a-specific-token "Direct link to Get all the pools for a specific token")
To list all pools for a token (insert the token address in the query below):
query MyQuery { pools(where: {token: "YOUR_TOKEN_ADDRESS_HERE"}) { createdAtBlockNumber createdAtTimestamp flowRate id totalMembers totalUnits admin { isSuperApp } }}
### Get all the pools for a specific pool admin[](https://docs.superfluid.org/docs/sdk/distributions/subgraph#get-all-the-pools-for-a-specific-pool-admin "Direct link to Get all the pools for a specific pool admin")
To list all pools for a pool admin (insert the pool admin address in the query below):
query MyQuery { pools(first: 10, where: {admin: "YOUR_POOL_ADMIN_ADDRESS_HERE"}) { totalUnits totalMembers flowRate createdAtBlockNumber token { id isSuperToken symbol } }}
Explore more queries[](https://docs.superfluid.org/docs/sdk/distributions/subgraph#explore-more-queries "Direct link to Explore more queries")
------------------------------------------------------------------------------------------------------------------------------------------------
Explore more queries using the [Superfluid Subgraph Playground](https://console.superfluid.finance/subgraph)
.
* [Querying Different Networks](https://docs.superfluid.org/docs/sdk/distributions/subgraph#querying-different-networks)
* [Superfluid Explorer](https://docs.superfluid.org/docs/sdk/distributions/subgraph#superfluid-explorer)
* [Subgraph Networks](https://docs.superfluid.org/docs/sdk/distributions/subgraph#subgraph-networks)
* [Resources](https://docs.superfluid.org/docs/sdk/distributions/subgraph#resources)
* [Helpful Tips](https://docs.superfluid.org/docs/sdk/distributions/subgraph#helpful-tips)
* [Notable Breaking Changes](https://docs.superfluid.org/docs/sdk/distributions/subgraph#notable-breaking-changes)
* [Schema Overview](https://docs.superfluid.org/docs/sdk/distributions/subgraph#schema-overview)
* [Event Entities](https://docs.superfluid.org/docs/sdk/distributions/subgraph#event-entities)
* [Higher Order Level Entities (HOL)](https://docs.superfluid.org/docs/sdk/distributions/subgraph#higher-order-level-entities-hol)
* [Aggregate Entities](https://docs.superfluid.org/docs/sdk/distributions/subgraph#aggregate-entities)
* [Query Examples](https://docs.superfluid.org/docs/sdk/distributions/subgraph#query-examples)
* [Super Token Data Query](https://docs.superfluid.org/docs/sdk/distributions/subgraph#super-token-data-query)
* [Get the pools that a user is a member of](https://docs.superfluid.org/docs/sdk/distributions/subgraph#get-the-pools-that-a-user-is-a-member-of)
* [Get all the pools for a specific token](https://docs.superfluid.org/docs/sdk/distributions/subgraph#get-all-the-pools-for-a-specific-token)
* [Get all the pools for a specific pool admin](https://docs.superfluid.org/docs/sdk/distributions/subgraph#get-all-the-pools-for-a-specific-pool-admin)
* [Explore more queries](https://docs.superfluid.org/docs/sdk/distributions/subgraph#explore-more-queries)
---
# Security & Bug Bounties | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/protocol/contribute/bug-bounties#__docusaurus_skipToContent_fallback)
On this page
Immunefi Bug Bounty Program[](https://docs.superfluid.org/docs/protocol/contribute/bug-bounties#immunefi-bug-bounty-program "Direct link to Immunefi Bug Bounty Program")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
We have an [Immunefi](https://immunefi.com/bounty/superfluid/)
bug bounty program with a maximum bounty of $100,000.
This program is focused on the protocol's smart contracts and is focused on preventing:
* Superfluid framework bugs
* Bugs in CFA/IDA in general
* Anything that would avoid streams from being closed
* Anything that would result in the sum of all account balances drifting significantly from the total supply
* Theft of tokens in third party wrapper contracts
* Other unexpected behavior in any super token contracts
**Learn more here:**
For more details, please visit the [Immunefi Bug Bounty Program page](https://immunefi.com/bounty/superfluid/)
.
Audit Resources[](https://docs.superfluid.org/docs/protocol/contribute/bug-bounties#audit-resources "Direct link to Audit Resources")
---------------------------------------------------------------------------------------------------------------------------------------
Superfluid has been audited on multiple occasions, you can find these past audit reports here:
For the audit reports, check out the [Superfluid GitHub repository](https://github.com/superfluid-finance/protocol-monorepo/tree/dev/packages/ethereum-contracts/audits)
.
General Security Tips For Superfluid Developers[](https://docs.superfluid.org/docs/protocol/contribute/bug-bounties#general-security-tips-for-superfluid-developers "Direct link to General Security Tips For Superfluid Developers")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
* We recommend what every good security expert would recommend: full test coverage, separation of concerns, and using automated tools like GitHub Actions or [Trail of Bits](https://blog.trailofbits.com/2018/03/23/use-our-suite-of-ethereum-security-tools/)
' tools for fuzzing & static analysis
* Guides like [this one from Consensys](https://consensys.github.io/smart-contract-best-practices/)
can be helpful in understanding what to think about before deploying smart contracts to mainnet.
* If you're looking for inspiration on setting up your own GitHub Actions pipelines, you can find a breakdown of Superfluid's own GitHub Actions setup [here](https://github.com/superfluid-finance/protocol-monorepo/wiki/Superfluid-GitHub-Actions-Deep-Dive)
.
* Beyond this, we recommend that you continue to think about security & potential for loss of funds in the front end and off-chain components of your project (if you have them).
* For example, we highly recommend you adopt some of the same UX practices that we do in the [Superfluid dashboard](https://app.superfluid.finance/)
if you have a front end that allows people to create Superfluid streams.
* I.e., we let the user know that letting their balance hit zero before they close their stream will [lead to a liquidation](https://docs.superfluid.org/docs/protocol/advanced-topics/solvency/liquidations-and-toga)
.
### Security Tips for Building Super Apps[](https://docs.superfluid.org/docs/protocol/contribute/bug-bounties#security-tips-for-building-super-apps "Direct link to Security Tips for Building Super Apps")
* Be careful that your application does not get jailed unexpectedly.
* We have detailed information [here](https://docs.superfluid.finance/superfluid/developers/super-apps/super-app#super-app-rules-jail-system)
regarding the jail system and how to avoid a jailed Super App, but one of the most common reasons for a jailed super app is an unexpected revert in either the `beforeAgreementTerminated` or `afterAgreementTerminated` callbacks.
### Custom Super Tokens[](https://docs.superfluid.org/docs/protocol/contribute/bug-bounties#custom-super-tokens "Direct link to Custom Super Tokens")
* In general, we advise sticking to the existing Super Token interfaces seen [here](https://github.com/superfluid-finance/protocol-monorepo/tree/dev/packages/ethereum-contracts/contracts/interfaces/tokens)
unless you have a good reason not to.
* If you want to deviate from this, we strongly encourage you to reach out to the Superfluid developer team in the #dev-support channel in our [Discord](https://discord.superfluid.finance/)
.
* [Immunefi Bug Bounty Program](https://docs.superfluid.org/docs/protocol/contribute/bug-bounties#immunefi-bug-bounty-program)
* [Audit Resources](https://docs.superfluid.org/docs/protocol/contribute/bug-bounties#audit-resources)
* [General Security Tips For Superfluid Developers](https://docs.superfluid.org/docs/protocol/contribute/bug-bounties#general-security-tips-for-superfluid-developers)
* [Security Tips for Building Super Apps](https://docs.superfluid.org/docs/protocol/contribute/bug-bounties#security-tips-for-building-super-apps)
* [Custom Super Tokens](https://docs.superfluid.org/docs/protocol/contribute/bug-bounties#custom-super-tokens)
---
# Solvency Dashboard | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/protocol/advanced-topics/solvency/solvency-dashboard#__docusaurus_skipToContent_fallback)
Click on the link below to find the solvency dashboard for the Superfluid protocol.
[The Solvency Dashboard](https://superfluid.metabaseapp.com/public/dashboard/a074474a-3c03-4368-84f9-a87761f5d902)
note
"Slot" refers to the solvency period during which the liquidation was executed.
> Slot 1: Patrician Period
>
> Slot 2: Pleb Period
>
> Slot 3: Pirate Period
See this [**explainer**](https://docs.superfluid.org/docs/protocol/advanced-topics/solvency/liquidations-and-toga#patricians-plebs-and-pirates-3ps)
for further details.
---
# Super Apps in Depth | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/understand-super-apps#__docusaurus_skipToContent_fallback)
On this page
### **What is a Super App?**[](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/understand-super-apps#what-is-a-super-app "Direct link to what-is-a-super-app")
Super Apps are smart contracts registered with the Superfluid Protocol, allowing them to **react to Super Agreements** (like money streams). They are similar to ERC777 hooks but for Super Agreements.
_(1)-372b51bfacc2bd87c4f83010d6e22626.png)
_The Tradeable Cashflow NFT_
Super Apps can execute custom logic in response to streaming-related actions. A great example is the [tradeable cashflow NFT contract](https://github.com/superfluid-finance/super-examples/tree/c784d239557d6fb5e56a2c8951ac4353256d611d/projects/tradeable-cashflow)
, which automatically opens a new stream from the NFT contract to the owner of the NFT upon receiving a stream.
Callbacks in Super Apps are triggered by these actions:
1. A flow is opened with the Super App as the `receiver`.
2. A flow involving the Super App as the `receiver` is updated.
3. A flow is closed by the Super App's counterparty.
These callbacks can execute any arbitrary logic, enabling a wide range of possibilities for Super Apps.
### Super App Configuration[](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/understand-super-apps#super-app-configuration "Direct link to Super App Configuration")
Super Apps need to be registered with the Superfluid Protocol to use callbacks. Here's how to register a Super App:
// Example registration code for a Super Appuint256 configWord = SuperAppDefinitions.APP_LEVEL_FINAL | SuperAppDefinitions.BEFORE_AGREEMENT_CREATED_NOOP | SuperAppDefinitions.BEFORE_AGREEMENT_UPDATED_NOOP | SuperAppDefinitions.BEFORE_AGREEMENT_TERMINATED_NOOP;string memory registrationKey = ""; // Can be empty for testnet deployments_host.registerAppWithKey(configWord, registrationKey);
The `APP_LEVEL_FINAL` flag ensures that the callbacks run in the first app in a chain of Super Apps. The `_NOOP` designations specify which callbacks are not used, avoiding unnecessary reverts.
For mainnet deployments, pre-approval is required for registering Super Apps. Check out the [Super App White-listing Guide](https://github.com/superfluid-finance/protocol-monorepo/wiki/Super-App-White-listing-Guide)
for more information.
### Super App Stream Buffers[](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/understand-super-apps#super-app-stream-buffers "Direct link to Super App Stream Buffers")
When creating a Superfluid stream, an up-front buffer is taken to ensure the protocol's security. These deposits vary based on whether the stream is sent to a Super App and whether it's on testnet or mainnet.
For example, on testnets, the deposit is 1 hour x `flowRate` for non-Super Apps and up to 2 hours x `flowRate` for Super Apps. On mainnet, these values are 4 hours and 8 hours x `flowRate`, respectively.
### Super App Callbacks[](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/understand-super-apps#super-app-callbacks "Direct link to Super App Callbacks")
Super App callbacks are triggered in response to certain actions in Superfluid agreements:
* When a stream is created, updated, or closed involving a Super App.
* Before and after these actions occur, different callbacks are executed.
Callback Anatomy:
function beforeAgreementCreated( ISuperToken /*superToken*/, address /*agreementClass*/, bytes32 /*agreementId*/, bytes calldata /*agreementData*/, bytes calldata /*ctx*/) external view virtual override returns (bytes memory /*cbdata*/){ revert("Unsupported callback - Before Agreement Created");}
function afterAgreementCreated( ISuperToken /*superToken*/, address /*agreementClass*/, bytes32 /*agreementId*/, bytes calldata /*agreementData*/, bytes calldata /*cbdata*/, bytes calldata /*ctx*/) external virtual override returns (bytes memory /*newCtx*/){ revert("Unsupported callback - After Agreement Created");}
### Super App Rules (Jail System)[](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/understand-super-apps#super-app-rules-jail-system "Direct link to Super App Rules (Jail System)")
Super Apps must comply with specific rules to avoid being jailed. These rules ensure the security and proper functioning of the protocol.
1. Super Apps cannot revert in the termination callback.
2. Super Apps must not become insolvent.
3. Operations within the termination callback must adhere to a gas limit.
4. The `ctx` data must be correctly handled in the termination callback.
#### Checking for Jailing[](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/understand-super-apps#checking-for-jailing "Direct link to Checking for Jailing")
To check if a Super App is jailed, call `isAppJailed` on the Superfluid Host contract with the Super App's address. This can be done on Etherscan or through the Superfluid subgraph.
note
For more details on the Jail system and Super App rules, visit the [Superfluid documentation](https://docs.superfluid.finance/superfluid)
.
### Conclusion[](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/understand-super-apps#conclusion "Direct link to Conclusion")
Super Apps offer a versatile framework for building complex, reactive financial applications on the Superfluid Protocol. By understanding their mechanics, rules, and potential, developers can create innovative solutions for real-time finance.
* [**What is a Super App?**](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/understand-super-apps#what-is-a-super-app)
* [Super App Configuration](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/understand-super-apps#super-app-configuration)
* [Super App Stream Buffers](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/understand-super-apps#super-app-stream-buffers)
* [Super App Callbacks](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/understand-super-apps#super-app-callbacks)
* [Super App Rules (Jail System)](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/understand-super-apps#super-app-rules-jail-system)
* [Conclusion](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/understand-super-apps#conclusion)
---
# Token Explorer Submission | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/protocol/contribute/submit-token-dashboard#__docusaurus_skipToContent_fallback)
On this page
You want your token to show up on the [Superfluid Explorer](https://explorer.superfluid.finance/)
? Look no further. In order to list a new token on the [Superfluid Explorer](https://explorer.superfluid.finance/)
and have it visible in our Dashboard, please follow the steps below.
Disclaimer
If your token looks like a potential scam or we can't find reliable information about your project/company, we reserve the right to avoid listing it on our visual Dashboard.
Steps to List Your Token[](https://docs.superfluid.org/docs/protocol/contribute/submit-token-dashboard#steps-to-list-your-token "Direct link to Steps to List Your Token")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
### 1\. Fill out the form[](https://docs.superfluid.org/docs/protocol/contribute/submit-token-dashboard#1-fill-out-the-form "Direct link to 1. Fill out the form")
You will find the form below. If you prefer, you can also access it [here](https://airtable.com/appxGogNpt64ImOFH/shrzOcdK9eveDmRWV)
.
### 2\. Issue Created[](https://docs.superfluid.org/docs/protocol/contribute/submit-token-dashboard#2-issue-created "Direct link to 2. Issue Created")
When you submit the Airtable form, it auto-generates a GitHub issue in our Token Assets repository. You can find the issues [here](https://github.com/superfluid-finance/assets/issues)
.
The Superfluid team will use the informations from the issue to add the token to the Explorer and to our protocol resolver. Hang tight!
### 3\. Confirmation[](https://docs.superfluid.org/docs/protocol/contribute/submit-token-dashboard#3-confirmation "Direct link to 3. Confirmation")
The issue will be closed upon completion or rejection. Wait for a confirmation by the Superfluid team to the Discord handle you provided in the form before sharing publicly that your token is now live on Superfluid.
If you don't hear back from us within a week or need more information on the listing process, please feel free to reach out via email at [support@superfluid.finance](mailto:support@superfluid.finance)
or reach out to us in the Support Channel of our [Discord](https://discord.gg/pPzPEDMVua)
.
* [Steps to List Your Token](https://docs.superfluid.org/docs/protocol/contribute/submit-token-dashboard#steps-to-list-your-token)
* [1\. Fill out the form](https://docs.superfluid.org/docs/protocol/contribute/submit-token-dashboard#1-fill-out-the-form)
* [2\. Issue Created](https://docs.superfluid.org/docs/protocol/contribute/submit-token-dashboard#2-issue-created)
* [3\. Confirmation](https://docs.superfluid.org/docs/protocol/contribute/submit-token-dashboard#3-confirmation)
---
# Quickstart | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/deploy-a-super-app#__docusaurus_skipToContent_fallback)
On this page
Inroduction[](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/deploy-a-super-app#inroduction "Direct link to Inroduction")
-------------------------------------------------------------------------------------------------------------------------------------------------
Super Apps are smart contracts registered with the Superfluid Protocol, allowing them to **react to actions of the Superfluid protocol** (like flow creations, flow updates and flow deletions).
_(1)-372b51bfacc2bd87c4f83010d6e22626.png)
_Super App Illustration_
This guide provides a simple example of how to deploy a Super App using the [CFASuperAppBase](https://github.com/superfluid-finance/protocol-monorepo/blob/dev/packages/ethereum-contracts/contracts/apps/CFASuperAppBase.sol)
.
About this Guide
This guide provides a basic example of deploying a Super App using the CFASuperAppBase contract. For more advanced Super App development, refer to the [Super Apps in Depth](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/understand-super-apps)
.
Dont overcomplicate it !
For most use cases, the CFASuperAppBase is sufficient. It simplifies the callback process and reduces redundancy.
CFASuperAppBase - Simplifying Super App Development[](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/deploy-a-super-app#cfasuperappbase---simplifying-super-app-development "Direct link to CFASuperAppBase - Simplifying Super App Development")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
### What is [CFASuperAppBase](https://github.com/superfluid-finance/protocol-monorepo/blob/dev/packages/ethereum-contracts/contracts/apps/CFASuperAppBase.sol)
?[](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/deploy-a-super-app#what-is-cfasuperappbase "Direct link to what-is-cfasuperappbase")
[CFASuperAppBase](https://github.com/superfluid-finance/protocol-monorepo/blob/dev/packages/ethereum-contracts/contracts/apps/CFASuperAppBase.sol)
is an inheritable base contract designed to streamline the development of Super Apps. It abstracts the complexities involved in writing callbacks and reduces redundancy.
_(2)-da900c31d4d35c431ed9efe1ce2c5b6f.png)
_CFASuperAppBase Illustration_
Example
onFlowCreated is a more intuitive function than afterAgreementCreated.
### Key Features of CFASuperAppBase[](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/deploy-a-super-app#key-features-of-cfasuperappbase "Direct link to Key Features of CFASuperAppBase")
* **Intuitive Callback Functions**: CFASuperAppBase consolidates callback development into three functions (`onFlowCreated`, `onFlowUpdated`, `onFlowDeleted`) with user-friendly parameters.
* **Ease of Use**: Simplifies the callback process compared to the original SuperAppBase, making it more accessible for developers.
#### Importing and Using CFASuperAppBase[](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/deploy-a-super-app#importing-and-using-cfasuperappbase "Direct link to Importing and Using CFASuperAppBase")
// Example Codeimport { CFASuperAppBase } from "@superfluid-finance/ethereum-contracts/contracts/apps/CFASuperAppBase.sol";contract SomeSuperAppContract is CFASuperAppBase { // Your contract implementation}
#### Constructor Arguments[](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/deploy-a-super-app#constructor-arguments "Direct link to Constructor Arguments")
constructor( ISuperfluid host_, bool activateOnCreated, bool activateOnUpdated, bool activateOnDeleted) // Constructor implementation
* **`host_`**: Superfluid Host address for your target network.
* **Activation Flags**: Indicate which callbacks (`onFlowCreated`, `onFlowUpdated`, `onFlowDeleted`) your Super App will use.
### Token Acceptance[](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/deploy-a-super-app#token-acceptance "Direct link to Token Acceptance")
Override the `isAcceptedSuperToken` function to specify which Super Tokens can trigger the Super App's callbacks.
function isAcceptedSuperToken(ISuperToken /*superToken*/) public view virtual returns (bool) { return true; // Default implementation}
### Callback Functions[](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/deploy-a-super-app#callback-functions "Direct link to Callback Functions")
#### onFlowCreated[](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/deploy-a-super-app#onflowcreated "Direct link to onFlowCreated")
Override for logic when a new flow to the Super App is created.
function onFlowCreated( ISuperToken superToken, address sender, bytes calldata ctx) internal virtual returns (bytes memory /*newCtx*/) { // Your logic here}
#### onFlowUpdated[](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/deploy-a-super-app#onflowupdated "Direct link to onFlowUpdated")
Override for logic when an existing flow to the Super App is updated.
function onFlowUpdated( ISuperToken superToken, address sender, int96 previousFlowRate, uint256 lastUpdated, bytes calldata ctx) internal virtual returns (bytes memory /*newCtx*/) { // Your logic here}
#### onFlowDeleted[](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/deploy-a-super-app#onflowdeleted "Direct link to onFlowDeleted")
Override for logic when an existing flow to the Super App is deleted. Note: This callback must not revert to avoid jailing the Super App.
function onFlowDeleted( ISuperToken superToken, address sender, address receiver, int96 previousFlowRate, uint256 lastUpdated, bytes calldata ctx) internal virtual returns (bytes memory /*newCtx*/) { // Your logic here}
Registering a Super App[](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/deploy-a-super-app#registering-a-super-app "Direct link to Registering a Super App")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Deploying a Super App involves integration with the Superfluid Protocol and compliance with its governance for activation. For your Super App to be recognized by the protocol, you must register it with the Superfluid Host contract. If you deploy your Super App on a testnet, you can call the function `selfRegister` to register it.
This is how the function looks on the CFASuperAppBase:
function selfRegister( bool activateOnCreated, bool activateOnUpdated, bool activateOnDeleted ) public { HOST.registerApp(getConfigWord(activateOnCreated, activateOnUpdated, activateOnDeleted)); }
If you are deploying on a mainnet or a network with permissioned registration, you will need to follow the registration process outlined in [Registering a Super App](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/register)
.
* [Inroduction](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/deploy-a-super-app#inroduction)
* [CFASuperAppBase - Simplifying Super App Development](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/deploy-a-super-app#cfasuperappbase---simplifying-super-app-development)
* [What is CFASuperAppBase?](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/deploy-a-super-app#what-is-cfasuperappbase)
* [Key Features of CFASuperAppBase](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/deploy-a-super-app#key-features-of-cfasuperappbase)
* [Token Acceptance](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/deploy-a-super-app#token-acceptance)
* [Callback Functions](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/deploy-a-super-app#callback-functions)
* [Registering a Super App](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/deploy-a-super-app#registering-a-super-app)
---
# Callbacks | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/callbacks#__docusaurus_skipToContent_fallback)
On this page
Super App callbacks play a pivotal role in how Super Apps interact with the Superfluid Protocol. These callbacks are invoked in response to specific events related to Super Agreements.
Callback Invocation Conditions[](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/callbacks#callback-invocation-conditions "Direct link to Callback Invocation Conditions")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Depending on the Super Agreement involved, the callbacks are triggered under different scenarios. The following table outlines these conditions:
| Agreement | Callback | Condition |
| --- | --- | --- |
| CFAv1 | beforeAgreementCreated, afterAgreementCreated | A stream to a Super App is created. |
| CFAv1 | beforeAgreementUpdated, afterAgreementUpdated | A stream to a Super App is updated. |
| CFAv1 | beforeAgreementTerminated, afterAgreementTerminated | A stream to a Super App is deleted. |
| IDAv1 | beforeAgreementCreated, afterAgreementCreated | A subscription (with zero units) to an index published by a Super App is approved. |
| IDAv1 | beforeAgreementUpdated, afterAgreementUpdated | A subscription (with units) to an index published by a Super App is approved. |
| IDAv1 | beforeAgreementTerminated, afterAgreementTerminated | A subscription to an index published by a Super App is revoked. |
| IDAv1 | beforeAgreementUpdated, afterAgreementUpdated | A subscription to an index published by a Super App is claimed |
| IDAv1 | beforeAgreementCreated, afterAgreementCreated | Units of an index are issued to a Super App if the units were previously zero. |
| IDAv1 | beforeAgreementUpdated, afterAgreementUpdated | Units of an index are issued to a Super App if the units were previously non-zero. |
| IDAv1 | beforeAgreementTerminated, afterAgreementTerminated | Units of an index issued to a Super App are deleted. |
Callback Origin[](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/callbacks#callback-origin "Direct link to Callback Origin")
----------------------------------------------------------------------------------------------------------------------------------------------------
The Superfluid protocol itself triggers these callbacks on-chain in response to various actions performed within the Constant Flow Agreement contract. The protocol checks if a Super App is involved in a transaction and, if so, executes the relevant callbacks.
### Anatomy of Super App Callbacks[](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/callbacks#anatomy-of-super-app-callbacks "Direct link to Anatomy of Super App Callbacks")
Below are examples of Super App callbacks and their structure:
function beforeAgreementCreated( ISuperToken /*superToken*/, address /*agreementClass*/, bytes32 /*agreementId*/, bytes calldata /*agreementData*/, bytes calldata /*ctx*/) external view virtual override returns (bytes memory /*cbdata*/) { revert("Unsupported callback - Before Agreement Created");}
function afterAgreementCreated( ISuperToken /*superToken*/, address /*agreementClass*/, bytes32 /*agreementId*/, bytes calldata /*agreementData*/, bytes calldata /*cbdata*/, bytes calldata /*ctx*/) external virtual override returns (bytes memory /*newCtx*/) { revert("Unsupported callback - After Agreement Created");}
#### Callback Execution[](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/callbacks#callback-execution "Direct link to Callback Execution")
* `beforeAgreement` callbacks are executed before the corresponding agreement contract action. They are `view` functions and can return data to be used in `afterAgreement` callbacks.
* `afterAgreement` callbacks are executed after the agreement contract action. They can implement logic based on the outcome of the agreement action and the data returned from `beforeAgreement` callbacks.
#### Callback Parameters[](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/callbacks#callback-parameters "Direct link to Callback Parameters")
* **`ISuperToken`**: The Super Token used in the transaction.
* **`address`**: Address of the Constant Flow Agreement contract.
* **`agreementId`**: A unique identifier for the agreement.
* **`agreementData`**: Encoded data of the agreement details.
* **`cbdata`**: Data returned from `beforeAgreement` callbacks (applicable to `afterAgreement` callbacks).
* **`ctx`**: Context of the transaction, essential for understanding the background of the callback invocation.
### Utilizing Callbacks[](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/callbacks#utilizing-callbacks "Direct link to Utilizing Callbacks")
Understanding and effectively using these callbacks is crucial for Super App developers. Each callback serves a specific purpose and offers the flexibility to execute custom logic in response to changes in Super Agreements.
CallAgreement vs CallAgreementWithContext[](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/callbacks#callagreement-vs-callagreementwithcontext "Direct link to CallAgreement vs CallAgreementWithContext")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
If you're making a call to a Superfluid agreement inside of a Super App callback, you should remember that you need to "receive a context, and return a context" by using the `callAgreementWithContext` function. If you're not making this call inside of a Super App callback, you should use `callAgreement`.
note
Note that this is a highly technical section for those looking to understand lower level features of the protocol. If you're looking to create, update, and delete streams or work with the instant distribution agreement in your super app callbacks, you can refer to the [SuperTokenV1Library](https://github.com/superfluid-finance/super-examples/blob/main/projects/tradeable-cashflow/contracts/RedirectAll.sol#L223)
to perform these operations in a single line of code.
### In Depth[](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/callbacks#in-depth "Direct link to In Depth")
When calling the host contract to trigger actions related to the constant flow agreement (CFA) or instant distribution agreement (IDA), you may use either `callAgreement` or `callAgreementWithContext`. Both of these functions allow you to pass in an encoded call to the agreement you'd like to interact with, as well as an optional `userData` value. The `callAgreementWithContext` function will perform the same actions as the `callAgreement` function, but it also enables you to pass in a new context value (abbreviated `ctx` ) to your function call.
Keep in mind that `callAgreementWithContext` is designed for use within Super Apps - if this function is run outside of a Super App, then `callAgreementWithContext` will fail due to this statement:
require( context.appAddress == msg.sender, "SF: callAgreementWithContext from wrong address");
`callAgreementWithContext` is primarily meant for use within Super App callbacks. Each Super App callback will be passed a context value (`ctx`) from the host contract (as the Superfluid host contract is the _caller_ of each callback). This `ctx` value is what needs to be passed to any call you want to make to the Superfluid host contract _inside_ of your callback (this goes for all operations which create, update, and delete flows in these callbacks). As a reminder, the logic within the 'host' contract can be found in `Superfluid.sol`.
The process looks like this:
Click here to show the code
//a function which we'll use to create a flow within a callbackfunction _createFlowInCallback( bytes calldata ctx, ISuperfluid _host, IConstantFlowAgreementV1 _cfa, ISuperfluidToken _acceptedToken, address _receiver, int96 _flowRate ) private returns (bytes memory newCtx) { newCtx = ctx; (newCtx,) = _host.callAgreementwithContext( _cfa, abi.encodeWithSelector( _cfa.deleteFlow.selector, _acceptedToken, address(this), _receiver, new bytes(0) // placeholder ), "0x", //placeholder userdata value newCtx //passing in the context from the super app callback ); }function afterAgreementCreated( ISuperToken _superToken, address _agreementClass, bytes32, // _agreementId, bytes calldata /*_agreementData*/, bytes calldata ,// _cbdata, bytes calldata _ctx) external override onlyExpected(_superToken, _agreementClass) onlyHost returns (bytes memory newCtx){//passing in the ctx which is sent to the callback here return _createFlowInCallback(_ctx, _host, _cfa, _acceptedToken, _receiver, _flowrate); }
You can also do this in a much easier way by using our new CFA Library, which abstracts away the need to use `host.callAgreement` or `host.callAgreementWithContext` directly.
Click here to show the code
using CFALibraryV1 for CFALibraryV1.InitData; //initialize cfaV1 variable CFALibraryV1.InitData public cfaV1; constructor( ISuperfluid host ) { //initialize InitData struct, and set equal to cfaV1 cfaV1 = CFALibraryV1.InitData( host, IConstantFlowAgreementV1( address(host.getAgreementClass( keccak256("org.superfluid-finance.agreements.ConstantFlowAgreement.v1") )) ) ); }function afterAgreementCreated( ISuperToken _superToken, address _agreementClass, bytes32, // _agreementId, bytes calldata /*_agreementData*/, bytes calldata ,// _cbdata, bytes calldata _ctx) external override onlyExpected(_superToken, _agreementClass) onlyHost returns (bytes memory newCtx){//passing in the ctx which is sent to the callback here//createFlowWithCtx makes use of callAgreementWithContext return cfaV1.createFlowWithCtx(_ctx, receiver, token, flowRate);}
You may have another scenario in which you want to make additional calls to the host contract after you first run `callAgreementWithContext`. If you do this, you can save the value returned by the first `callAgreementWithContext` function to a new variable, then pass this value to your next call to `callAgreementWithContext` . The takeaway here is that you need to pass the most recent iteration of `ctx` when creating, updating, or deleting flows inside Super App callbacks. You can see this done here with the CFA Library:
Click here to show the code
using CFALibraryV1 for CFALibraryV1.InitData; //initialize cfaV1 variable CFALibraryV1.InitData public cfaV1; constructor( ISuperfluid host ) { //initialize InitData struct, and set equal to cfaV1 cfaV1 = CFALibraryV1.InitData( host, IConstantFlowAgreementV1( address(host.getAgreementClass( keccak256("org.superfluid-finance.agreements.ConstantFlowAgreement.v1") )) ) ); }function afterAgreementCreated( ISuperToken _superToken, address _agreementClass, bytes32, // _agreementId, bytes calldata /*_agreementData*/, bytes calldata ,// _cbdata, bytes calldata _ctx) external override onlyExpected(_superToken, _agreementClass) onlyHost returns (bytes memory newCtx){ newCtx = cfaV1.createFlowWithCtx(_ctx, receiver, token, flowRate); //passing in the ctx which is sent to the callback here newCtx = cfaV1.createFlowWithCtx(newCtx, receiver, token, flowRate); //passing in the ctx which is returned from the first call here }
One final item to note is to not manually change the value of `ctx` when it's used within a Super App. `Ctx` is formatted in a very specific way within a struct that is compiled to bytecode by the protocol, and it's not meant to be manipulated directly. If you wish to pass in userData to your function call, this can be done by simply adding the `userData` value in as a parameter:
Click here to show the code
//using the CFA Library:function afterAgreementCreated( ISuperToken _superToken, address _agreementClass, bytes32, // _agreementId, bytes calldata /*_agreementData*/, bytes calldata ,// _cbdata, bytes calldata _ctx) external override onlyExpected(_superToken, _agreementClass) onlyHost returns (bytes memory newCtx){ //passing in the ctx which is sent to the callback here //createFlowWithCtx makes use of callAgreementWithContext return cfaV1.createFlowWithCtx(_ctx, receiver, token, flowRate, userData);}//using a low level callfunction afterAgreementCreated( ISuperToken _superToken, address _agreementClass, bytes32, // _agreementId, bytes calldata /*_agreementData*/, bytes calldata ,// _cbdata, bytes calldata _ctx) external override onlyExpected(_superToken, _agreementClass) onlyHost returns (bytes memory newCtx) { newCtx = _ctx; (newCtx,) = _host.callAgreementwithContext( _cfa, abi.encodeWithSelector( _cfa.deleteFlow.selector, _acceptedToken, address(this), _receiver, new bytes(0) // placeholder ), userData, //userData goes here newCtx //passing in the context from the super app callback ); }
If you read through the Superfluid codebase, you'll see that nearly every state changing operation will return a context value. This `ctx` value helps to provide additional internal accounting for the protocol to enhance security, and it allows you to decode it and make use of values like userData inside Super Apps. When making calls within your Super Apps, keep in mind that you need to pass in updated context values if you want to make use of the callbacks properly. Remember: if you need to run callAgreement within a Super App callback, you'll need to use `callAgreementWithContext` and pass in `ctx`.
* [Callback Invocation Conditions](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/callbacks#callback-invocation-conditions)
* [Callback Origin](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/callbacks#callback-origin)
* [Anatomy of Super App Callbacks](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/callbacks#anatomy-of-super-app-callbacks)
* [Utilizing Callbacks](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/callbacks#utilizing-callbacks)
* [CallAgreement vs CallAgreementWithContext](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/callbacks#callagreement-vs-callagreementwithcontext)
* [In Depth](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/callbacks#in-depth)
---
# Registering Super Apps | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/register#__docusaurus_skipToContent_fallback)
On this page
Overview[](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/register#overview "Direct link to Overview")
------------------------------------------------------------------------------------------------------------------------------
To activate a Super App, you need to register it in the [Superfluid Host](https://docs.superfluid.org/docs/concepts/advanced-topics/superfluid-host)
contract. This registration is crucial for enabling the Super App's business logic to be invoked via agreement hooks.
Registration Process[](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/register#registration-process "Direct link to Registration Process")
------------------------------------------------------------------------------------------------------------------------------------------------------------------
### Basic Registration[](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/register#basic-registration "Direct link to Basic Registration")
You can
1. Use the `registerApp` method of the host contract.
2. Two ways to register:
* Self-registration: `registerApp(configWord)`
* Registration by another account: `registerApp(app, configWord)`
### Permissioned vs. Non-Permissioned Networks[](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/register#permissioned-vs-non-permissioned-networks "Direct link to Permissioned vs. Non-Permissioned Networks")
Some networks require additional steps for Super App registration. Here's how to check:
1. Query `host.APP_WHITE_LISTING_ENABLED()` on your target network.
2. You can do this via the Superfluid Explorer:
* Go to the "protocol" section (e.g., [Polygon Mainnet Explorer](https://explorer.superfluid.finance/matic/protocol)
)
* Click the Explorer link for "Host"
* Navigate to Contract -> Read as Proxy
* Expand "WHITE\_LISTING\_ENABLED"

* If `false`: Standard registration process applies
* If `true`: Follow the permissioned registration process below
Permissioned App Registration[](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/register#permissioned-app-registration "Direct link to Permissioned App Registration")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
If your target network requires permissioned registration:
1. Get a "deployer" account whitelisted (can be an EOA or a contract)
2. Choose your deployment strategy:
a) For a single Super App:
* Register in the constructor or initialize method
* Use `host.registerApp(configWord)`
* Whitelist the EOA making this transaction
b) For multiple Super App instances (e.g., factory pattern):
* Whitelist a contract as the deployer
* Use `host.registerApp(app, configWord)` from this contract
### Important Notes[](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/register#important-notes "Direct link to Important Notes")
* Using `registerApp(configWord)`: `tx.origin` must be whitelisted
* Using `registerApp(app, configWord)`: `msg.sender` must be whitelisted
Need Help?[](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/register#need-help "Direct link to Need Help?")
-----------------------------------------------------------------------------------------------------------------------------------
If you need assistance or have questions about the process:
1. Join our [Discord](http://discord.superfluid.finance/)
2. Contact the Superfluid dev team in the #development channel
Code Examples[](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/register#code-examples "Direct link to Code Examples")
---------------------------------------------------------------------------------------------------------------------------------------------
Here are some basic examples to illustrate the registration process:
// Self-registration in constructorconstructor(ISuperfluid host, uint256 configWord) { host.registerApp(configWord);}// Registration by another accountfunction registerSuperApp(ISuperfluid host, ISuperApp app, uint256 configWord) external { host.registerApp(app, configWord);}
Remember to adjust these examples based on your specific Super App implementation and network requirements.
* [Overview](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/register#overview)
* [Registration Process](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/register#registration-process)
* [Basic Registration](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/register#basic-registration)
* [Permissioned vs. Non-Permissioned Networks](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/register#permissioned-vs-non-permissioned-networks)
* [Permissioned App Registration](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/register#permissioned-app-registration)
* [Important Notes](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/register#important-notes)
* [Need Help?](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/register#need-help)
* [Code Examples](https://docs.superfluid.org/docs/protocol/advanced-topics/super-apps/register#code-examples)
---
# Stream Scheduler | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/stream-scheduler#__docusaurus_skipToContent_fallback)
On this page
What’s the Stream Scheduler?[](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/stream-scheduler#whats-the-stream-scheduler "Direct link to What’s the Stream Scheduler?")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
The Stream Scheduler is a Superfluid feature that enables you to:
1. Schedule the closing of an existing stream.
2. Schedule the start of a new stream.
3. Schedule both the start and end of a new stream.
This functionality is accessible directly from the Superfluid Dashboard after [approval for access](https://use.superfluid.finance/schedulestreams)
and can also be implemented using underlying contracts and off-chain automations.
[Click here for full a guide on how to set up a Stream Scheduler Automation](https://superfluidhq.notion.site/Setting-Up-Stream-Scheduling-551888de690e402caee50e8d87cb6930)
Why Schedule Streams?[](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/stream-scheduler#why-schedule-streams "Direct link to Why Schedule Streams?")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Scheduling streams offers automation for streams with fixed start and/or end dates. This is particularly useful for applications like payroll, subscriptions, and token vesting. By default, Superfluid streams are perpetual, running until manually canceled or until the balance is depleted. The Stream Scheduler allows for automated stream management, eliminating the need for manual intervention.
Example:[](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/stream-scheduler#example "Direct link to Example:")
--------------------------------------------------------------------------------------------------------------------------------------
Consider the following scenario, visualized in these [Miro diagrams](https://miro.com/app/board/uXjVP--AM4I=/?share_link_id=524959909457)
:
1. **Stream Scheduling**: On January 1st, you grant operator permissions to the Stream Scheduler contract and schedule a stream with the following details:
* **Flow Rate**: 100 DAIx/mo.
* **To**: Alice’s account
* **Start**: March 1st, 2023, at 12:00 am
* **End**: March 20th, 2023, at 12:00 am
_(4)-6f79d4e656fe1c14fcd8d5f59ae18b50.png)
2. **Stream Initiation**: On March 1st, the scheduled stream from you to Alice commences.
_(2)-02fdfdb970d5b802d5a83a1405c543e2.png)
3. **Stream Cancellation**: On March 20th, the stream from you to Alice is automatically canceled.
-28788324d4927a900b1d747a91d3d576.png)
Setting Up Stream Scheduling[](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/stream-scheduler#setting-up-stream-scheduling "Direct link to Setting Up Stream Scheduling")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
The Stream Scheduler is a versatile tool that enhances the functionality of Superfluid streams by automating their creation and termination based on predefined schedules. This feature simplifies the management of streaming payments, especially in use cases like subscription services, vesting schedules, and regular disbursements.
To get started with stream scheduling and unlock the full potential of automated streaming in Superfluid, follow the detailed guide provided in the link below.
[Click here for full a guide on how to set up a Stream Scheduler Automation](https://superfluidhq.notion.site/Setting-Up-Stream-Scheduling-551888de690e402caee50e8d87cb6930)
* [What’s the Stream Scheduler?](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/stream-scheduler#whats-the-stream-scheduler)
* [Why Schedule Streams?](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/stream-scheduler#why-schedule-streams)
* [Example:](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/stream-scheduler#example)
* [Setting Up Stream Scheduling](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/stream-scheduler#setting-up-stream-scheduling)
---
# Auto-Wrap | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/auto-wrap#__docusaurus_skipToContent_fallback)
On this page
What's Auto-Wrap?[](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/auto-wrap#whats-auto-wrap "Direct link to What's Auto-Wrap?")
---------------------------------------------------------------------------------------------------------------------------------------------------------
Auto-Wrap is an automated token wrapping system that automatically wraps ERC20 tokens to Super Tokens just in time to keep your streams running. When your Super Token balance reaches a certain lower threshold, Auto-Wrap steps in and wraps enough tokens into the needed Super Token on your behalf to ensure you never run out of balance, as that would make all streams stop.
[Click here for full a guide on how to set up an Auto-Wrap Automation](https://www.notion.so/superfluidhq/Setting-Up-Superfluid-Auto-Wrap-9a565d53bbee4bdc953cc2a656c43761)
Why Auto-Wrap?[](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/auto-wrap#why-auto-wrap "Direct link to Why Auto-Wrap?")
-------------------------------------------------------------------------------------------------------------------------------------------------
Most organizations don’t hold their assets as Super Tokens. DAOs are more likely to hold USDC than USDCx in their treasury to limit exposure to third party protocols. So when a DAO is paying contributors in streams of USDCx they need to ensure they periodically wrap additional USDC in USDCx to keep their streams running. This can be a tedious manual process because it requires you to:
1. Periodically check the Super Token balance to make sure it isn’t reaching zero.
2. If it is approaching zero, manually wrap additional USDC to USDCx to avoid running out of USDCx balance.
With Auto-Wrap, this manual process is fully automated. The system keeps monitoring a wallet balance of a specific token (i.e. USDC) and when it’s too low (normally less than 2 days worth of outgoing streaming) it automatically wraps a variable amount (normally 7 days worth of outgoing streaming) to keep streams running over time. All payroll admin needs to do is ensure they’re holding enough USDC in their wallet - the wrapping part is taken care of by Auto-Wrap.
Example[](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/auto-wrap#example "Direct link to Example")
-----------------------------------------------------------------------------------------------------------------------------
1. Auto-Wrap identifies that the DAO’s DAIx balance is running low. In this example, it’s less than a two days away from running out of DAIx.
_(3)_(1)-28a6d7cb8fafcab68aadef51a9fa82fa.png)
2. Auto-Wrap automatically steps in and replenishes the DAIx balance back to seven days worth of outgoing stream so payment continues without interruption. No manual triggering required!
-5fd4548046835dd3e454c2af9ef52644.png)
Setting Up Auto-Wrap[](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/auto-wrap#setting-up-auto-wrap "Direct link to Setting Up Auto-Wrap")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
To set up Auto-Wrap for your organization, follow the detailed guide available here:
[Click here for full a guide on how to set up an Auto-Wrap Automation](https://www.notion.so/superfluidhq/Setting-Up-Superfluid-Auto-Wrap-9a565d53bbee4bdc953cc2a656c43761)
* [What's Auto-Wrap?](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/auto-wrap#whats-auto-wrap)
* [Why Auto-Wrap?](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/auto-wrap#why-auto-wrap)
* [Example](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/auto-wrap#example)
* [Setting Up Auto-Wrap](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/auto-wrap#setting-up-auto-wrap)
---
# Vesting Scheduler | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/vesting-scheduler#__docusaurus_skipToContent_fallback)
On this page
What’s the Vesting Scheduler?[](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/vesting-scheduler#whats-the-vesting-scheduler "Direct link to What’s the Vesting Scheduler?")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
The Vesting Scheduler is a sophisticated smart contract designed for setting up token vesting schedules. It's non-custodial and operates by moving tokens directly from your wallet or Safe to a specified recipient. The contract includes options for adding cliffs, after which it initiates a linear vesting process through a Superfluid stream, ensuring the recipient receives tokens directly in their wallet without any need for claiming.
While the integration of the Vesting Scheduler into the Superfluid Dashboard is forthcoming, it's already possible to interact directly with the contract alongside off-chain automations. Detailed instructions for setting up automated vesting can be found in the documentation.
[Click here for a full guide on Setting Up Automated Vesting](https://www.notion.so/superfluidhq/Setting-Up-Automated-Vesting-f3e11a257a2d4b0b89210def54a59278)
Why Automate Vesting with Superfluid?[](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/vesting-scheduler#why-automate-vesting-with-superfluid "Direct link to Why Automate Vesting with Superfluid?")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Automating vesting with Superfluid streamlines the process of setting up a linear vesting schedule, providing flexibility and security. With this system, you can:
* Implement linear vesting schedules with customizable cliffs.
* Specify both the cliff date/time and amount.
* Determine your total vesting amount and its time frame.
* Retain all tokens in your wallet or Safe until they're transferred to the recipient.
Example:[](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/vesting-scheduler#example "Direct link to Example:")
---------------------------------------------------------------------------------------------------------------------------------------
1. **Initial Setup**: On January 1st, you aim to vest 400 AMZNx to Alice from February 1st to June 1st. The vesting schedule includes a cliff of 100 AMZNx on March 1st.
_(3)-c1daa2e0dbb0578785de1475a804b4f9.png)
2. **Cliff Execution**: On March 1st, the cliff amount of 100 AMZNx is transferred to Alice, and the linear vesting stream begins. No action is needed on February 1st due to the cliff.
_(1)-44777dbc0a8a30ed7998f644c9775a41.png)
3. **Completion of Vesting**: By June 1st, the vesting process is complete, and the stream to Alice is cancelled.
_(2)-4e6c88a438ee0b7edff0f9809b6e2d0a.png)
Setting Up Vesting Scheduling[](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/vesting-scheduler#setting-up-vesting-scheduling "Direct link to Setting Up Vesting Scheduling")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
The scheduler's integration with Superfluid streams adds an extra layer of convenience, eliminating the need for manual intervention once the schedule is set. This not only saves time but also ensures accuracy and reliability in the vesting process.
If you're interested in setting up automated vesting, you can find detailed instructions in the link below.
[Click here for a full guide on Setting Up Automated Vesting](https://www.notion.so/superfluidhq/Setting-Up-Automated-Vesting-f3e11a257a2d4b0b89210def54a59278)
* [What’s the Vesting Scheduler?](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/vesting-scheduler#whats-the-vesting-scheduler)
* [Why Automate Vesting with Superfluid?](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/vesting-scheduler#why-automate-vesting-with-superfluid)
* [Example:](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/vesting-scheduler#example)
* [Setting Up Vesting Scheduling](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/vesting-scheduler#setting-up-vesting-scheduling)
---
# Stream Accounting API | Superfluid | Stream Money Every Second
[Skip to main content](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/stream-accounting-api#__docusaurus_skipToContent_fallback)
On this page
Overview[](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/stream-accounting-api#overview "Direct link to Overview")
--------------------------------------------------------------------------------------------------------------------------------------------
* Streams move value every second, but accounting tools usually record value transfer on a non-real-time basis (typically monthly).
* The Stream Accounting API represents streams in a format consumable by traditional accounting tools.
[Click here for full a guide on how to set up a Stream Accounting API Automation](https://superfluidhq.notion.site/Using-the-Stream-Accounting-API-3d161745acfe4750acf43c546f84c724)
Functionality[](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/stream-accounting-api#functionality "Direct link to Functionality")
-----------------------------------------------------------------------------------------------------------------------------------------------------------
* The Stream Accounting API is RESTful and exposes an endpoint for fetching stream data across all Superfluid tokens and networks.
* It allows chopping up the amounts an address has been streaming into accounting periods of your choice (monthly, daily, even hourly).
### Token Pricing[](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/stream-accounting-api#token-pricing "Direct link to Token Pricing")
* Price information for each period is available if the token has Coingecko tracking.
* You can select price granularity to get average prices over a timeframe or instantaneous prices for each period.
### Accommodating Flow Rate Updates[](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/stream-accounting-api#accommodating-flow-rate-updates "Direct link to Accommodating Flow Rate Updates")
* The API accommodates changes in stream flow rates, segmenting data into separate periods for each flow rate.
### Outgoing & Incoming[](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/stream-accounting-api#outgoing--incoming "Direct link to Outgoing & Incoming")
* Accounts for both outgoing and incoming streams, denoting incoming streams with positive values and outbound streams with negative values.
### All Networks and All Tokens[](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/stream-accounting-api#all-networks-and-all-tokens "Direct link to All Networks and All Tokens")
* Supports all Superfluid-supported networks and tokens through the [Superfluid Subgraphs](https://docs.superfluid.finance/superfluid/developers/subgraph)
.
Example[](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/stream-accounting-api#example "Direct link to Example")
-----------------------------------------------------------------------------------------------------------------------------------------
* Alice pays Bob in a stream of 0.1 ETHx per month.
-0e555ddc5611d216dfbde1ddf75484cc.png)
* Fetch accounting info for Alice's stream from June 1st to September 15th.
_(2)_(1)-d02e4232236ac595d628ae2155e32a22.png)
* Stream Accounting API provides data for the requested months.
_(2)-0f2104762b8fdcf9ba8258f2017333c3.png)
* If Alice updates her stream to 0.2 ETHx/month on September 15th.
_(5)-a12fd4193bc2c7c182459a0ff40b2b58.png)
* Request accounting info from June 1st to December 1st.
_(3)-0cfcf53cc20814759845bac1f7d296a5.png)
* API provides data for the updated period.
_(5)-14016a151a34668a48e8a259a7798e66.png)
Setting up the Stream Accounting API[](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/stream-accounting-api#setting-up-the-stream-accounting-api "Direct link to Setting up the Stream Accounting API")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
The Stream Accounting API is a robust tool for integrating real-time streaming data into your traditional accounting systems. Whether you're tracking incoming or outgoing streams, dealing with various tokens, or managing complex stream adjustments, the API provides the flexibility and precision required for accurate financial reporting.
You will find below a link to a full guide on how to set up a Stream Accounting API Automation.
[Click here for full a guide on how to set up a Stream Accounting API Automation](https://superfluidhq.notion.site/Using-the-Stream-Accounting-API-3d161745acfe4750acf43c546f84c724)
* [Overview](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/stream-accounting-api#overview)
* [Functionality](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/stream-accounting-api#functionality)
* [Token Pricing](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/stream-accounting-api#token-pricing)
* [Accommodating Flow Rate Updates](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/stream-accounting-api#accommodating-flow-rate-updates)
* [Outgoing & Incoming](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/stream-accounting-api#outgoing--incoming)
* [All Networks and All Tokens](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/stream-accounting-api#all-networks-and-all-tokens)
* [Example](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/stream-accounting-api#example)
* [Setting up the Stream Accounting API](https://docs.superfluid.org/docs/protocol/advanced-topics/automations/stream-accounting-api#setting-up-the-stream-accounting-api)
---