Skip to main content

CFAv1Forwarder

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 through the Constant Flow Agreement (CFA).

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 Interact Off-Chain section of this documentation.

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

error CFA_FWD_INVALID_FLOW_RATE()

_cfa

contract IConstantFlowAgreementV1 _cfa

Fn constructor

function constructor(
contract ISuperfluid host
)
public

Parameters

NameTypeDescription
hostcontract ISuperfluid

Fn setFlowrate

Parameters

NameTypeDescription
tokencontract ISuperTokenSuper token address
receiveraddressThe receiver of the flow
flowrateint96The wanted flowrate in wad/second. Only positive values are valid here.

Return Values

NameTypeDescription
[0]boolbool

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

Parameters

NameTypeDescription
tokencontract ISuperTokenSuper token address
senderaddressThe sender of the flow
receiveraddressThe receiver of the flow
flowrateint96The wanted flowrate in wad/second. Only positive values are valid here.

Return Values

NameTypeDescription
[0]boolbool

Like setFlowrate, but can be invoked by an account with flowOperator permissions on behalf of the sender account.

Fn getFlowrate

Currently, only 0 or 1 flows can exist between 2 accounts. This may change in the future.

Parameters

NameTypeDescription
tokencontract ISuperTokenSuper token address
senderaddressThe sender of the flow
receiveraddressThe receiver of the flow

Return Values

NameTypeDescription
flowrateint96The 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

Parameters

NameTypeDescription
tokencontract ISuperTokenSuper token address
senderaddressThe sender of the flow
receiveraddressThe receiver of the flow

Return Values

NameTypeDescription
lastUpdateduint256Timestamp of last update (flowrate change) or zero if no flow exists
flowrateint96Current flowrate of the flow or zero if no flow exists
deposituint256Deposit amount locked as security buffer during the lifetime of the flow
owedDeposituint256Extra 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

function getBufferAmountByFlowrate(
contract ISuperToken token,
int96 flowrate
)
external
returns (uint256 bufferAmount)

Parameters

NameTypeDescription
tokencontract ISuperTokenSuper token address
flowrateint96The flowrate for which the buffer amount is calculated

Return Values

NameTypeDescription
bufferAmountuint256The 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

Parameters

NameTypeDescription
tokencontract ISuperTokenSuper token address
accountaddressAccount to query

Return Values

NameTypeDescription
flowrateint96The net flowrate (aggregate incoming minus aggregate outgoing flowrate), can be negative.

Get the net flowrate of an account.

Fn getAccountFlowInfo

Parameters

NameTypeDescription
tokencontract ISuperTokenSuper token address
accountaddressAccount to query

Return Values

NameTypeDescription
lastUpdateduint256Timestamp of last update of a flow to or from the account (flowrate change)
flowrateint96Current net aggregate flowrate
deposituint256Aggregate deposit amount currently locked as security buffer for outgoing flows
owedDeposituint256Aggregate 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

Parameters

NameTypeDescription
tokencontract ISuperTokenSuper token address
senderaddressSender address of the flow
receiveraddressReceiver address of the flow
flowrateint96The flowrate in wad/second to be set initially
userDatabytes(optional) User data to be set. Should be set to zero if not needed.

Return Values

NameTypeDescription
[0]boolbool

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

Parameters

NameTypeDescription
tokencontract ISuperTokenSuper token address
senderaddressSender address of the flow
receiveraddressReceiver address of the flow
flowrateint96The flowrate in wad/second the flow should be updated to
userDatabytes(optional) User data to be set. Should be set to zero if not needed.

Return Values

NameTypeDescription
[0]boolbool

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

Parameters

NameTypeDescription
tokencontract ISuperTokenSuper token address
senderaddressSender address of the flow
receiveraddressReceiver address of the flow
userDatabytes(optional) User data to be set. Should be set to zero if not needed.

Return Values

NameTypeDescription
[0]boolbool

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

Parameters

NameTypeDescription
tokencontract ISuperTokenSuper token address
flowOperatoraddressAccount to which permissions are granted

Return Values

NameTypeDescription
[0]boolbool

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

Parameters

NameTypeDescription
tokencontract ISuperTokenSuper token address
flowOperatoraddressAccount from which permissions are revoked

Return Values

NameTypeDescription
[0]boolbool

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

Parameters

NameTypeDescription
tokencontract ISuperTokenSuper token address
flowOperatoraddressAccount for which permissions are set on behalf of msg.sender
permissionsuint8Bitmask for create/update/delete permission flags. See library FlowOperatorDefinitions
flowrateAllowanceint96Max. flowrate in wad/second the operator can set for individual flows.

Return Values

NameTypeDescription
[0]boolbool

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

Parameters

NameTypeDescription
tokencontract ISuperTokenSuper token address
senderaddressThe account which (possiby) granted permissions
flowOperatoraddressAccount to which (possibly) permissions were granted

Return Values

NameTypeDescription
permissionsuint8A bitmask of the permissions currently granted (or not) by sender to flowOperator
flowrateAllowanceint96Max. 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

Parameters

NameTypeDescription
tokencontract ISuperToken
senderaddress
receiveraddress
flowrateint96

Fn _createFlow

Parameters

NameTypeDescription
tokencontract ISuperToken
senderaddress
receiveraddress
flowrateint96
userDatabytes

Fn _updateFlow

Parameters

NameTypeDescription
tokencontract ISuperToken
senderaddress
receiveraddress
flowrateint96
userDatabytes

Fn _deleteFlow

Parameters

NameTypeDescription
tokencontract ISuperToken
senderaddress
receiveraddress
userDatabytes

Fn _updateFlowOperatorPermissions

Parameters

NameTypeDescription
tokencontract ISuperToken
flowOperatoraddress
permissionsuint8
flowrateAllowanceint96