Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 107306788 | 923 days ago | 0 ETH | ||||
| 107306788 | 923 days ago | 0 ETH | ||||
| 107306788 | 923 days ago | 0 ETH | ||||
| 107306788 | 923 days ago | 0 ETH | ||||
| 107306788 | 923 days ago | 0 ETH | ||||
| 107066111 | 929 days ago | 0 ETH | ||||
| 107066111 | 929 days ago | 0 ETH | ||||
| 107066111 | 929 days ago | 0 ETH | ||||
| 107066111 | 929 days ago | 0 ETH | ||||
| 107066111 | 929 days ago | 0 ETH | ||||
| 107066111 | 929 days ago | 0 ETH | ||||
| 107066111 | 929 days ago | 0 ETH | ||||
| 107066111 | 929 days ago | 0 ETH | ||||
| 107066111 | 929 days ago | 0 ETH | ||||
| 107066111 | 929 days ago | 0 ETH | ||||
| 107066111 | 929 days ago | 0 ETH | ||||
| 107066111 | 929 days ago | 0 ETH | ||||
| 107066111 | 929 days ago | 0 ETH | ||||
| 107064043 | 929 days ago | 0 ETH | ||||
| 107064043 | 929 days ago | 0 ETH | ||||
| 107064043 | 929 days ago | 0 ETH | ||||
| 107064043 | 929 days ago | 0 ETH | ||||
| 107064043 | 929 days ago | 0 ETH | ||||
| 107063317 | 929 days ago | 0 ETH | ||||
| 107063317 | 929 days ago | 0 ETH |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
PCOLicenseParamsFacet
Compiler Version
v0.8.16+commit.07a7930e
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;
import "../libraries/LibPCOLicenseParams.sol";
import "../interfaces/IPCOLicenseParamsStore.sol";
import {ISuperfluid} from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol";
import {ISuperToken} from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperToken.sol";
import {OwnableInternal} from "@solidstate/contracts/access/ownable/OwnableInternal.sol";
import "../../beneficiary/interfaces/ICFABeneficiary.sol";
import {OwnableStorage} from "@solidstate/contracts/access/ownable/OwnableStorage.sol";
/// @title Public access to global Claimer parameters
contract PCOLicenseParamsFacet is IPCOLicenseParamsStore {
using OwnableStorage for OwnableStorage.Layout;
modifier onlyOwner() {
require(
msg.sender == OwnableStorage.layout().owner,
"Ownable: sender must be owner"
);
_;
}
/**
* @notice Initialize.
* - Must be the contract owner
* @param beneficiary Beneficiary of funds.
* @param paymentToken Payment token.
* @param host Superfluid host
* @param perSecondFeeNumerator The numerator of the network-wide per second contribution fee.
* @param perSecondFeeDenominator The denominator of the network-wide per second contribution fee.
* @param penaltyNumerator The numerator of the penalty to pay to reject a bid.
* @param penaltyDenominator The denominator of the penalty to pay to reject a bid.
* @param bidPeriodLengthInSeconds Bid period length in seconds
* @param reclaimAuctionLength when the required bid amount reaches its minimum value.
*/
function initializeParams(
ICFABeneficiary beneficiary,
ISuperToken paymentToken,
ISuperfluid host,
uint256 perSecondFeeNumerator,
uint256 perSecondFeeDenominator,
uint256 penaltyNumerator,
uint256 penaltyDenominator,
uint256 bidPeriodLengthInSeconds,
uint256 reclaimAuctionLength,
uint256 minForSalePrice
) external onlyOwner {
LibPCOLicenseParams.DiamondStorage storage ds = LibPCOLicenseParams
.diamondStorage();
ds.beneficiary = beneficiary;
ds.paymentToken = paymentToken;
ds.host = host;
ds.perSecondFeeNumerator = perSecondFeeNumerator;
ds.perSecondFeeDenominator = perSecondFeeDenominator;
ds.penaltyNumerator = penaltyNumerator;
ds.penaltyDenominator = penaltyDenominator;
ds.bidPeriodLengthInSeconds = bidPeriodLengthInSeconds;
ds.reclaimAuctionLength = reclaimAuctionLength;
ds.minForSalePrice = minForSalePrice;
}
/// @notice Superfluid Host
function getHost() external view override returns (ISuperfluid) {
LibPCOLicenseParams.DiamondStorage storage ds = LibPCOLicenseParams
.diamondStorage();
return ds.host;
}
/// @notice Set Superfluid Host
function setHost(ISuperfluid host) external onlyOwner {
LibPCOLicenseParams.DiamondStorage storage ds = LibPCOLicenseParams
.diamondStorage();
ds.host = host;
}
/// @notice Payment token
function getPaymentToken() external view override returns (ISuperToken) {
LibPCOLicenseParams.DiamondStorage storage ds = LibPCOLicenseParams
.diamondStorage();
return ds.paymentToken;
}
/// @notice Set Payment Token
function setPaymentToken(ISuperToken paymentToken) external onlyOwner {
LibPCOLicenseParams.DiamondStorage storage ds = LibPCOLicenseParams
.diamondStorage();
ds.paymentToken = paymentToken;
}
/// @notice Beneficiary
function getBeneficiary() external view override returns (ICFABeneficiary) {
LibPCOLicenseParams.DiamondStorage storage ds = LibPCOLicenseParams
.diamondStorage();
return ds.beneficiary;
}
/// @notice Set Beneficiary
function setBeneficiary(ICFABeneficiary beneficiary) external onlyOwner {
LibPCOLicenseParams.DiamondStorage storage ds = LibPCOLicenseParams
.diamondStorage();
ds.beneficiary = beneficiary;
}
/// @notice The numerator of the network-wide per second contribution fee.
function getPerSecondFeeNumerator()
external
view
override
returns (uint256)
{
LibPCOLicenseParams.DiamondStorage storage ds = LibPCOLicenseParams
.diamondStorage();
return ds.perSecondFeeNumerator;
}
/// @notice Set Per Second Fee Numerator
function setPerSecondFeeNumerator(uint256 perSecondFeeNumerator)
external
onlyOwner
{
LibPCOLicenseParams.DiamondStorage storage ds = LibPCOLicenseParams
.diamondStorage();
ds.perSecondFeeNumerator = perSecondFeeNumerator;
}
/// @notice The denominator of the network-wide per second contribution fee.
function getPerSecondFeeDenominator()
external
view
override
returns (uint256)
{
LibPCOLicenseParams.DiamondStorage storage ds = LibPCOLicenseParams
.diamondStorage();
return ds.perSecondFeeDenominator;
}
/// @notice Set Per Second Fee Denominator
function setPerSecondFeeDenominator(uint256 perSecondFeeDenominator)
external
onlyOwner
{
LibPCOLicenseParams.DiamondStorage storage ds = LibPCOLicenseParams
.diamondStorage();
ds.perSecondFeeDenominator = perSecondFeeDenominator;
}
/// @notice The numerator of the penalty rate.
function getPenaltyNumerator() external view override returns (uint256) {
LibPCOLicenseParams.DiamondStorage storage ds = LibPCOLicenseParams
.diamondStorage();
return ds.penaltyNumerator;
}
/// @notice Set Penalty Numerator
function setPenaltyNumerator(uint256 penaltyNumerator) external onlyOwner {
LibPCOLicenseParams.DiamondStorage storage ds = LibPCOLicenseParams
.diamondStorage();
ds.penaltyNumerator = penaltyNumerator;
}
/// @notice The denominator of the penalty rate.
function getPenaltyDenominator() external view override returns (uint256) {
LibPCOLicenseParams.DiamondStorage storage ds = LibPCOLicenseParams
.diamondStorage();
return ds.penaltyDenominator;
}
/// @notice Set Penalty Denominator
function setPenaltyDenominator(uint256 penaltyDenominator)
external
onlyOwner
{
LibPCOLicenseParams.DiamondStorage storage ds = LibPCOLicenseParams
.diamondStorage();
ds.penaltyDenominator = penaltyDenominator;
}
/// @notice the final/minimum required bid reached and maintained at the end of the auction.
function getReclaimAuctionLength()
external
view
override
returns (uint256)
{
LibPCOLicenseParams.DiamondStorage storage ds = LibPCOLicenseParams
.diamondStorage();
return ds.reclaimAuctionLength;
}
/// @notice Set Reclaim Auction Length
function setReclaimAuctionLength(uint256 reclaimAuctionLength)
external
onlyOwner
{
LibPCOLicenseParams.DiamondStorage storage ds = LibPCOLicenseParams
.diamondStorage();
ds.reclaimAuctionLength = reclaimAuctionLength;
}
/// @notice Bid period length in seconds
function getBidPeriodLengthInSeconds()
external
view
override
returns (uint256)
{
LibPCOLicenseParams.DiamondStorage storage ds = LibPCOLicenseParams
.diamondStorage();
return ds.bidPeriodLengthInSeconds;
}
/// @notice Set Bid Period Length in seconds
function setBidPeriodLengthInSeconds(uint256 bidPeriodLengthInSeconds)
external
onlyOwner
{
LibPCOLicenseParams.DiamondStorage storage ds = LibPCOLicenseParams
.diamondStorage();
ds.bidPeriodLengthInSeconds = bidPeriodLengthInSeconds;
}
/// @notice Minimum for sale price
function getMinForSalePrice() external view override returns (uint256) {
LibPCOLicenseParams.DiamondStorage storage ds = LibPCOLicenseParams
.diamondStorage();
return ds.minForSalePrice;
}
/// @notice Set minimum for sale price
function setMinForSalePrice(uint256 minForSalePrice) external onlyOwner {
LibPCOLicenseParams.DiamondStorage storage ds = LibPCOLicenseParams
.diamondStorage();
ds.minForSalePrice = minForSalePrice;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;
import {ISuperfluid} from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol";
import {CFAv1Library} from "@superfluid-finance/ethereum-contracts/contracts/apps/CFAv1Library.sol";
import {ISuperToken} from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperToken.sol";
import "../../beneficiary/interfaces/ICFABeneficiary.sol";
library LibPCOLicenseParams {
bytes32 private constant STORAGE_POSITION =
keccak256("diamond.standard.diamond.storage.LibPCOLicenseParams");
struct DiamondStorage {
/// @notice Beneficiary of funds.
ICFABeneficiary beneficiary;
/// @notice Payment token.
ISuperToken paymentToken;
/// @notice Superfluid host
ISuperfluid host;
/// @notice The numerator of the network-wide per second contribution fee.
uint256 perSecondFeeNumerator;
/// @notice The denominator of the network-wide per second contribution fee.
uint256 perSecondFeeDenominator;
/// @notice The numerator of the penalty to pay to reject a bid.
uint256 penaltyNumerator;
/// @notice The denominator of the penalty to pay to reject a bid.
uint256 penaltyDenominator;
/// @notice Bid period length in seconds
uint256 bidPeriodLengthInSeconds;
/// @notice when the required bid amount reaches its minimum value.
uint256 reclaimAuctionLength;
/// @notice Minimum for sale price
uint256 minForSalePrice;
}
function diamondStorage()
internal
pure
returns (DiamondStorage storage ds)
{
bytes32 position = STORAGE_POSITION;
// solhint-disable-next-line no-inline-assembly
assembly {
ds.slot := position
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;
import {ISuperfluid} from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol";
import {ISuperToken} from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperToken.sol";
import "../../beneficiary/interfaces/ICFABeneficiary.sol";
interface IPCOLicenseParamsStore {
/**
* @notice Initialize.
* - Must be the contract owner
* @param beneficiary Beneficiary of funds.
* @param paymentToken Payment token.
* @param host Superfluid host
* @param perSecondFeeNumerator The numerator of the network-wide per second contribution fee.
* @param perSecondFeeDenominator The denominator of the network-wide per second contribution fee.
* @param penaltyNumerator The numerator of the penalty to pay to reject a bid.
* @param penaltyDenominator The denominator of the penalty to pay to reject a bid.
* @param bidPeriodLengthInSeconds Bid period length in seconds
* @param reclaimAuctionLength when the required bid amount reaches its minimum value.
*/
function initializeParams(
ICFABeneficiary beneficiary,
ISuperToken paymentToken,
ISuperfluid host,
uint256 perSecondFeeNumerator,
uint256 perSecondFeeDenominator,
uint256 penaltyNumerator,
uint256 penaltyDenominator,
uint256 bidPeriodLengthInSeconds,
uint256 reclaimAuctionLength,
uint256 minForSalePrice
) external;
/// @notice Superfluid Host
function getHost() external view returns (ISuperfluid);
/// @notice Set Superfluid Host
function setHost(ISuperfluid host) external;
/// @notice Payment token
function getPaymentToken() external view returns (ISuperToken);
/// @notice Set Payment Token
function setPaymentToken(ISuperToken paymentToken) external;
/// @notice Beneficiary
function getBeneficiary() external view returns (ICFABeneficiary);
/// @notice Set Beneficiary
function setBeneficiary(ICFABeneficiary beneficiary) external;
/// @notice The numerator of the network-wide per second contribution fee.
function getPerSecondFeeNumerator() external view returns (uint256);
/// @notice Set Per Second Fee Numerator
function setPerSecondFeeNumerator(uint256 perSecondFeeNumerator) external;
/// @notice The denominator of the network-wide per second contribution fee.
function getPerSecondFeeDenominator() external view returns (uint256);
/// @notice Set Per Second Fee Denominator
function setPerSecondFeeDenominator(uint256 perSecondFeeDenominator)
external;
/// @notice The numerator of the penalty rate.
function getPenaltyNumerator() external view returns (uint256);
/// @notice Set Penalty Numerator
function setPenaltyNumerator(uint256 penaltyNumerator) external;
/// @notice The denominator of the penalty rate.
function getPenaltyDenominator() external view returns (uint256);
/// @notice Set Penalty Denominator
function setPenaltyDenominator(uint256 penaltyDenominator) external;
/// @notice the final/minimum required bid reached and maintained at the end of the auction.
function getReclaimAuctionLength() external view returns (uint256);
/// @notice Set Reclaim Auction Length
function setReclaimAuctionLength(uint256 reclaimAuctionLength) external;
/// @notice Bid period length in seconds
function getBidPeriodLengthInSeconds() external view returns (uint256);
/// @notice Set Bid Period Length in seconds
function setBidPeriodLengthInSeconds(uint256 bidPeriodLengthInSeconds)
external;
/// @notice Minimum for sale price
function getMinForSalePrice() external view returns (uint256);
/// @notice Set minimum for sale price
function setMinForSalePrice(uint256 minForSalePrice) external;
}// SPDX-License-Identifier: AGPLv3
pragma solidity >= 0.8.2;
import { ISuperfluidGovernance } from "./ISuperfluidGovernance.sol";
import { ISuperfluidToken } from "./ISuperfluidToken.sol";
import { ISuperToken } from "./ISuperToken.sol";
import { ISuperTokenFactory } from "./ISuperTokenFactory.sol";
import { ISuperAgreement } from "./ISuperAgreement.sol";
import { ISuperApp } from "./ISuperApp.sol";
import {
BatchOperation,
ContextDefinitions,
FlowOperatorDefinitions,
SuperAppDefinitions,
SuperfluidGovernanceConfigs
} from "./Definitions.sol";
import { TokenInfo } from "../tokens/TokenInfo.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { IERC777 } from "@openzeppelin/contracts/token/ERC777/IERC777.sol";
/**
* @title Host interface
* @author Superfluid
* @notice This is the central contract of the system where super agreement, super app
* and super token features are connected.
*
* The Superfluid host contract is also the entry point for the protocol users,
* where batch call and meta transaction are provided for UX improvements.
*
*/
interface ISuperfluid {
/**************************************************************************
* Time
*
* > The Oracle: You have the sight now, Neo. You are looking at the world without time.
* > Neo: Then why can't I see what happens to her?
* > The Oracle: We can never see past the choices we don't understand.
* > - The Oracle and Neo conversing about the future of Trinity and the effects of Neo's choices
*************************************************************************/
function getNow() external view returns (uint256);
/**************************************************************************
* Governance
*************************************************************************/
/**
* @dev Get the current governance address of the Superfluid host
*/
function getGovernance() external view returns(ISuperfluidGovernance governance);
/**
* @dev Replace the current governance with a new one
*/
function replaceGovernance(ISuperfluidGovernance newGov) external;
/**
* @dev Governance replaced event
* @param oldGov Address of the old governance contract
* @param newGov Address of the new governance contract
*/
event GovernanceReplaced(ISuperfluidGovernance oldGov, ISuperfluidGovernance newGov);
/**************************************************************************
* Agreement Whitelisting
*************************************************************************/
/**
* @dev Register a new agreement class to the system
* @param agreementClassLogic Initial agreement class code
*
* @custom:modifiers
* - onlyGovernance
*/
function registerAgreementClass(ISuperAgreement agreementClassLogic) external;
/**
* @notice Agreement class registered event
* @dev agreementType is the keccak256 hash of: "org.superfluid-finance.agreements.<AGREEMENT_NAME>.<VERSION>"
* @param agreementType The agreement type registered
* @param code Address of the new agreement
*/
event AgreementClassRegistered(bytes32 agreementType, address code);
/**
* @dev Update code of an agreement class
* @param agreementClassLogic New code for the agreement class
*
* @custom:modifiers
* - onlyGovernance
*/
function updateAgreementClass(ISuperAgreement agreementClassLogic) external;
/**
* @notice Agreement class updated event
* @dev agreementType is the keccak256 hash of: "org.superfluid-finance.agreements.<AGREEMENT_NAME>.<VERSION>"
* @param agreementType The agreement type updated
* @param code Address of the new agreement
*/
event AgreementClassUpdated(bytes32 agreementType, address code);
/**
* @notice Check if the agreement type is whitelisted
* @dev agreementType is the keccak256 hash of: "org.superfluid-finance.agreements.<AGREEMENT_NAME>.<VERSION>"
*/
function isAgreementTypeListed(bytes32 agreementType) external view returns(bool yes);
/**
* @dev Check if the agreement class is whitelisted
*/
function isAgreementClassListed(ISuperAgreement agreementClass) external view returns(bool yes);
/**
* @notice Get agreement class
* @dev agreementType is the keccak256 hash of: "org.superfluid-finance.agreements.<AGREEMENT_NAME>.<VERSION>"
*/
function getAgreementClass(bytes32 agreementType) external view returns(ISuperAgreement agreementClass);
/**
* @dev Map list of the agreement classes using a bitmap
* @param bitmap Agreement class bitmap
*/
function mapAgreementClasses(uint256 bitmap)
external view
returns (ISuperAgreement[] memory agreementClasses);
/**
* @notice Create a new bitmask by adding a agreement class to it
* @dev agreementType is the keccak256 hash of: "org.superfluid-finance.agreements.<AGREEMENT_NAME>.<VERSION>"
* @param bitmap Agreement class bitmap
*/
function addToAgreementClassesBitmap(uint256 bitmap, bytes32 agreementType)
external view
returns (uint256 newBitmap);
/**
* @notice Create a new bitmask by removing a agreement class from it
* @dev agreementType is the keccak256 hash of: "org.superfluid-finance.agreements.<AGREEMENT_NAME>.<VERSION>"
* @param bitmap Agreement class bitmap
*/
function removeFromAgreementClassesBitmap(uint256 bitmap, bytes32 agreementType)
external view
returns (uint256 newBitmap);
/**************************************************************************
* Super Token Factory
**************************************************************************/
/**
* @dev Get the super token factory
* @return factory The factory
*/
function getSuperTokenFactory() external view returns (ISuperTokenFactory factory);
/**
* @dev Get the super token factory logic (applicable to upgradable deployment)
* @return logic The factory logic
*/
function getSuperTokenFactoryLogic() external view returns (address logic);
/**
* @dev Update super token factory
* @param newFactory New factory logic
*/
function updateSuperTokenFactory(ISuperTokenFactory newFactory) external;
/**
* @dev SuperToken factory updated event
* @param newFactory Address of the new factory
*/
event SuperTokenFactoryUpdated(ISuperTokenFactory newFactory);
/**
* @notice Update the super token logic to the latest
* @dev Refer to ISuperTokenFactory.Upgradability for expected behaviours
*/
function updateSuperTokenLogic(ISuperToken token) external;
/**
* @dev SuperToken logic updated event
* @param code Address of the new SuperToken logic
*/
event SuperTokenLogicUpdated(ISuperToken indexed token, address code);
/**************************************************************************
* App Registry
*************************************************************************/
/**
* @dev Message sender (must be a contract) declares itself as a super app.
* @custom:deprecated you should use `registerAppWithKey` or `registerAppByFactory` instead,
* because app registration is currently governance permissioned on mainnets.
* @param configWord The super app manifest configuration, flags are defined in
* `SuperAppDefinitions`
*/
function registerApp(uint256 configWord) external;
/**
* @dev App registered event
* @param app Address of jailed app
*/
event AppRegistered(ISuperApp indexed app);
/**
* @dev Message sender declares itself as a super app.
* @param configWord The super app manifest configuration, flags are defined in `SuperAppDefinitions`
* @param registrationKey The registration key issued by the governance, needed to register on a mainnet.
* @notice See https://github.com/superfluid-finance/protocol-monorepo/wiki/Super-App-White-listing-Guide
* On testnets or in dev environment, a placeholder (e.g. empty string) can be used.
* While the message sender must be the super app itself, the transaction sender (tx.origin)
* must be the deployer account the registration key was issued for.
*/
function registerAppWithKey(uint256 configWord, string calldata registrationKey) external;
/**
* @dev Message sender (must be a contract) declares app as a super app
* @param configWord The super app manifest configuration, flags are defined in `SuperAppDefinitions`
* @notice On mainnet deployments, only factory contracts pre-authorized by governance can use this.
* See https://github.com/superfluid-finance/protocol-monorepo/wiki/Super-App-White-listing-Guide
*/
function registerAppByFactory(ISuperApp app, uint256 configWord) external;
/**
* @dev Query if the app is registered
* @param app Super app address
*/
function isApp(ISuperApp app) external view returns(bool);
/**
* @dev Query app level
* @param app Super app address
*/
function getAppLevel(ISuperApp app) external view returns(uint8 appLevel);
/**
* @dev Get the manifest of the super app
* @param app Super app address
*/
function getAppManifest(
ISuperApp app
)
external view
returns (
bool isSuperApp,
bool isJailed,
uint256 noopMask
);
/**
* @dev Query if the app has been jailed
* @param app Super app address
*/
function isAppJailed(ISuperApp app) external view returns (bool isJail);
/**
* @dev Whitelist the target app for app composition for the source app (msg.sender)
* @param targetApp The target super app address
*/
function allowCompositeApp(ISuperApp targetApp) external;
/**
* @dev Query if source app is allowed to call the target app as downstream app
* @param app Super app address
* @param targetApp The target super app address
*/
function isCompositeAppAllowed(
ISuperApp app,
ISuperApp targetApp
)
external view
returns (bool isAppAllowed);
/**************************************************************************
* Agreement Framework
*
* Agreements use these function to trigger super app callbacks, updates
* app allowance and charge gas fees.
*
* These functions can only be called by registered agreements.
*************************************************************************/
/**
* @dev (For agreements) StaticCall the app before callback
* @param app The super app.
* @param callData The call data sending to the super app.
* @param isTermination Is it a termination callback?
* @param ctx Current ctx, it will be validated.
* @return cbdata Data returned from the callback.
*/
function callAppBeforeCallback(
ISuperApp app,
bytes calldata callData,
bool isTermination,
bytes calldata ctx
)
external
// onlyAgreement
// assertValidCtx(ctx)
returns(bytes memory cbdata);
/**
* @dev (For agreements) Call the app after callback
* @param app The super app.
* @param callData The call data sending to the super app.
* @param isTermination Is it a termination callback?
* @param ctx Current ctx, it will be validated.
* @return newCtx The current context of the transaction.
*/
function callAppAfterCallback(
ISuperApp app,
bytes calldata callData,
bool isTermination,
bytes calldata ctx
)
external
// onlyAgreement
// assertValidCtx(ctx)
returns(bytes memory newCtx);
/**
* @dev (For agreements) Create a new callback stack
* @param ctx The current ctx, it will be validated.
* @param app The super app.
* @param appAllowanceGranted App allowance granted so far.
* @param appAllowanceUsed App allowance used so far.
* @return newCtx The current context of the transaction.
*/
function appCallbackPush(
bytes calldata ctx,
ISuperApp app,
uint256 appAllowanceGranted,
int256 appAllowanceUsed,
ISuperfluidToken appAllowanceToken
)
external
// onlyAgreement
// assertValidCtx(ctx)
returns (bytes memory newCtx);
/**
* @dev (For agreements) Pop from the current app callback stack
* @param ctx The ctx that was pushed before the callback stack.
* @param appAllowanceUsedDelta App allowance used by the app.
* @return newCtx The current context of the transaction.
*
* @custom:security
* - Here we cannot do assertValidCtx(ctx), since we do not really save the stack in memory.
* - Hence there is still implicit trust that the agreement handles the callback push/pop pair correctly.
*/
function appCallbackPop(
bytes calldata ctx,
int256 appAllowanceUsedDelta
)
external
// onlyAgreement
returns (bytes memory newCtx);
/**
* @dev (For agreements) Use app allowance.
* @param ctx The current ctx, it will be validated.
* @param appAllowanceWantedMore See app allowance for more details.
* @param appAllowanceUsedDelta See app allowance for more details.
* @return newCtx The current context of the transaction.
*/
function ctxUseAllowance(
bytes calldata ctx,
uint256 appAllowanceWantedMore,
int256 appAllowanceUsedDelta
)
external
// onlyAgreement
// assertValidCtx(ctx)
returns (bytes memory newCtx);
/**
* @dev (For agreements) Jail the app.
* @param app The super app.
* @param reason Jail reason code.
* @return newCtx The current context of the transaction.
*/
function jailApp(
bytes calldata ctx,
ISuperApp app,
uint256 reason
)
external
// onlyAgreement
// assertValidCtx(ctx)
returns (bytes memory newCtx);
/**
* @dev Jail event for the app
* @param app Address of jailed app
* @param reason Reason the app is jailed (see Definitions.sol for the full list)
*/
event Jail(ISuperApp indexed app, uint256 reason);
/**************************************************************************
* Contextless Call Proxies
*
* NOTE: For EOAs or non-app contracts, they are the entry points for interacting
* with agreements or apps.
*
* NOTE: The contextual call data should be generated using
* abi.encodeWithSelector. The context parameter should be set to "0x",
* an empty bytes array as a placeholder to be replaced by the host
* contract.
*************************************************************************/
/**
* @dev Call agreement function
* @param agreementClass The agreement address you are calling
* @param callData The contextual call data with placeholder ctx
* @param userData Extra user data being sent to the super app callbacks
*/
function callAgreement(
ISuperAgreement agreementClass,
bytes calldata callData,
bytes calldata userData
)
external
//cleanCtx
//isAgreement(agreementClass)
returns(bytes memory returnedData);
/**
* @notice Call app action
* @dev Main use case is calling app action in a batch call via the host
* @param callData The contextual call data
*
* @custom:note See "Contextless Call Proxies" above for more about contextual call data.
*/
function callAppAction(
ISuperApp app,
bytes calldata callData
)
external
//cleanCtx
//isAppActive(app)
//isValidAppAction(callData)
returns(bytes memory returnedData);
/**************************************************************************
* Contextual Call Proxies and Context Utilities
*
* For apps, they must use context they receive to interact with
* agreements or apps.
*
* The context changes must be saved and returned by the apps in their
* callbacks always, any modification to the context will be detected and
* the violating app will be jailed.
*************************************************************************/
/**
* @dev Context Struct
*
* @custom:note on backward compatibility:
* - Non-dynamic fields are padded to 32bytes and packed
* - Dynamic fields are referenced through a 32bytes offset to their "parents" field (or root)
* - The order of the fields hence should not be rearranged in order to be backward compatible:
* - non-dynamic fields will be parsed at the same memory location,
* - and dynamic fields will simply have a greater offset than it was.
*/
struct Context {
//
// Call context
//
// callback level
uint8 appLevel;
// type of call
uint8 callType;
// the system timestamp
uint256 timestamp;
// The intended message sender for the call
address msgSender;
//
// Callback context
//
// For callbacks it is used to know which agreement function selector is called
bytes4 agreementSelector;
// User provided data for app callbacks
bytes userData;
//
// App context
//
// app allowance granted
uint256 appAllowanceGranted;
// app allowance wanted by the app callback
uint256 appAllowanceWanted;
// app allowance used, allowing negative values over a callback session
int256 appAllowanceUsed;
// app address
address appAddress;
// app allowance in super token
ISuperfluidToken appAllowanceToken;
}
function callAgreementWithContext(
ISuperAgreement agreementClass,
bytes calldata callData,
bytes calldata userData,
bytes calldata ctx
)
external
// requireValidCtx(ctx)
// onlyAgreement(agreementClass)
returns (bytes memory newCtx, bytes memory returnedData);
function callAppActionWithContext(
ISuperApp app,
bytes calldata callData,
bytes calldata ctx
)
external
// requireValidCtx(ctx)
// isAppActive(app)
returns (bytes memory newCtx);
function decodeCtx(bytes calldata ctx)
external pure
returns (Context memory context);
function isCtxValid(bytes calldata ctx) external view returns (bool);
/**************************************************************************
* Batch call
**************************************************************************/
/**
* @dev Batch operation data
*/
struct Operation {
// Operation type. Defined in BatchOperation (Definitions.sol)
uint32 operationType;
// Operation target
address target;
// Data specific to the operation
bytes data;
}
/**
* @dev Batch call function
* @param operations Array of batch operations
*/
function batchCall(Operation[] memory operations) external;
/**
* @dev Batch call function for trusted forwarders (EIP-2771)
* @param operations Array of batch operations
*/
function forwardBatchCall(Operation[] memory operations) external;
/**************************************************************************
* Function modifiers for access control and parameter validations
*
* While they cannot be explicitly stated in function definitions, they are
* listed in function definition comments instead for clarity.
*
* TODO: turning these off because solidity-coverage doesn't like it
*************************************************************************/
/* /// @dev The current superfluid context is clean.
modifier cleanCtx() virtual;
/// @dev Require the ctx being valid.
modifier requireValidCtx(bytes memory ctx) virtual;
/// @dev Assert the ctx being valid.
modifier assertValidCtx(bytes memory ctx) virtual;
/// @dev The agreement is a listed agreement.
modifier isAgreement(ISuperAgreement agreementClass) virtual;
// onlyGovernance
/// @dev The msg.sender must be a listed agreement.
modifier onlyAgreement() virtual;
/// @dev The app is registered and not jailed.
modifier isAppActive(ISuperApp app) virtual; */
}// SPDX-License-Identifier: AGPLv3
pragma solidity >= 0.8.0;
import { ISuperfluid } from "./ISuperfluid.sol";
import { ISuperfluidToken } from "./ISuperfluidToken.sol";
import { TokenInfo } from "../tokens/TokenInfo.sol";
import { IERC777 } from "@openzeppelin/contracts/token/ERC777/IERC777.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
/**
* @title Super token (Superfluid Token + ERC20 + ERC777) interface
* @author Superfluid
*/
interface ISuperToken is ISuperfluidToken, TokenInfo, IERC20, IERC777 {
/**
* @dev Initialize the contract
*/
function initialize(
IERC20 underlyingToken,
uint8 underlyingDecimals,
string calldata n,
string calldata s
) external;
/**************************************************************************
* TokenInfo & ERC777
*************************************************************************/
/**
* @dev Returns the name of the token.
*/
function name() external view override(IERC777, TokenInfo) returns (string memory);
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() external view override(IERC777, TokenInfo) returns (string memory);
/**
* @dev 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.
*
* @custom: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} and {IERC20-transfer}.
*/
function decimals() external view override(TokenInfo) returns (uint8);
/**************************************************************************
* ERC20 & ERC777
*************************************************************************/
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() external view override(IERC777, IERC20) returns (uint256);
/**
* @dev Returns the amount of tokens owned by an account (`owner`).
*/
function balanceOf(address account) external view override(IERC777, IERC20) returns(uint256 balance);
/**************************************************************************
* ERC20
*************************************************************************/
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* @return Returns Success a boolean value indicating whether the operation succeeded.
*
* @custom:emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external override(IERC20) returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* @notice This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external override(IERC20) view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* @return Returns Success a boolean value indicating whether the operation succeeded.
*
* @custom: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
*
* @custom:emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external override(IERC20) returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* @return Returns Success a boolean value indicating whether the operation succeeded.
*
* @custom:emits a {Transfer} event.
*/
function transferFrom(address sender, address recipient, uint256 amount) external override(IERC20) returns (bool);
/**
* @dev 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}.
*
* @custom:emits an {Approval} event indicating the updated allowance.
*
* @custom:requirements
* - `spender` cannot be the zero address.
*/
function increaseAllowance(address spender, uint256 addedValue) external returns (bool);
/**
* @dev 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}.
*
* @custom:emits an {Approval} event indicating the updated allowance.
*
* @custom:requirements
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/
function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool);
/**************************************************************************
* ERC777
*************************************************************************/
/**
* @dev 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.
*
* @custom:note For super token contracts, this value is always 1
*/
function granularity() external view override(IERC777) returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* @dev If send or receive hooks are registered for the caller and `recipient`,
* the corresponding functions will be called with `data` and empty
* `operatorData`. See {IERC777Sender} and {IERC777Recipient}.
*
* @custom:emits a {Sent} 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}
* interface.
*/
function send(address recipient, uint256 amount, bytes calldata data) external override(IERC777);
/**
* @dev Destroys `amount` tokens from the caller's account, reducing the
* total supply.
*
* If a send hook is registered for the caller, the corresponding function
* will be called with `data` and empty `operatorData`. See {IERC777Sender}.
*
* @custom:emits a {Burned} event.
*
* @custom:requirements
* - the caller must have at least `amount` tokens.
*/
function burn(uint256 amount, bytes calldata data) external override(IERC777);
/**
* @dev 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} and {operatorBurn}.
*/
function isOperatorFor(address operator, address tokenHolder) external override(IERC777) view returns (bool);
/**
* @dev Make an account an operator of the caller.
*
* See {isOperatorFor}.
*
* @custom:emits an {AuthorizedOperator} event.
*
* @custom:requirements
* - `operator` cannot be calling address.
*/
function authorizeOperator(address operator) external override(IERC777);
/**
* @dev Revoke an account's operator status for the caller.
*
* See {isOperatorFor} and {defaultOperators}.
*
* @custom:emits a {RevokedOperator} event.
*
* @custom:requirements
* - `operator` cannot be calling address.
*/
function revokeOperator(address operator) external override(IERC777);
/**
* @dev Returns the list of default operators. These accounts are operators
* for all token holders, even if {authorizeOperator} was never called on
* them.
*
* This list is immutable, but individual holders may revoke these via
* {revokeOperator}, in which case {isOperatorFor} will return false.
*/
function defaultOperators() external override(IERC777) view returns (address[] memory);
/**
* @dev 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 `data` and
* `operatorData`. See {IERC777Sender} and {IERC777Recipient}.
*
* @custom:emits a {Sent} 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}
* interface.
*/
function operatorSend(
address sender,
address recipient,
uint256 amount,
bytes calldata data,
bytes calldata operatorData
) external override(IERC777);
/**
* @dev 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 `data` and `operatorData`. See {IERC777Sender}.
*
* @custom:emits a {Burned} event.
*
* @custom:requirements
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
* - the caller must be an operator for `account`.
*/
function operatorBurn(
address account,
uint256 amount,
bytes calldata data,
bytes calldata operatorData
) external override(IERC777);
/**************************************************************************
* SuperToken custom token functions
*************************************************************************/
/**
* @dev Mint new tokens for the account
*
* @custom:modifiers
* - onlySelf
*/
function selfMint(
address account,
uint256 amount,
bytes memory userData
) external;
/**
* @dev Burn existing tokens for the account
*
* @custom:modifiers
* - onlySelf
*/
function selfBurn(
address account,
uint256 amount,
bytes memory userData
) external;
/**
* @dev 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
*/
function selfTransferFrom(
address sender,
address spender,
address recipient,
uint256 amount
) external;
/**
* @dev Give `spender`, `amount` allowance to spend the tokens of
* `account`.
*
* @custom:modifiers
* - onlySelf
*/
function selfApproveFor(
address account,
address spender,
uint256 amount
) external;
/**************************************************************************
* SuperToken extra functions
*************************************************************************/
/**
* @dev Transfer all available balance from `msg.sender` to `recipient`
*/
function transferAll(address recipient) external;
/**************************************************************************
* ERC20 wrapping
*************************************************************************/
/**
* @dev Return the underlying token contract
* @return tokenAddr Underlying token address
*/
function getUnderlyingToken() external view returns(address tokenAddr);
/**
* @dev Upgrade ERC20 to SuperToken.
* @param amount Number of tokens to be upgraded (in 18 decimals)
*
* @custom:note It will use `transferFrom` to get tokens. Before calling this
* function you should `approve` this contract
*/
function upgrade(uint256 amount) external;
/**
* @dev Upgrade ERC20 to SuperToken and transfer immediately
* @param to The account to received upgraded tokens
* @param amount Number of tokens to be upgraded (in 18 decimals)
* @param data User data for the TokensRecipient callback
*
* @custom:note It will use `transferFrom` to get tokens. Before calling this
* function you should `approve` this contract
*/
function upgradeTo(address to, uint256 amount, bytes calldata data) external;
/**
* @dev Token upgrade event
* @param account Account where tokens are upgraded to
* @param amount Amount of tokens upgraded (in 18 decimals)
*/
event TokenUpgraded(
address indexed account,
uint256 amount
);
/**
* @dev Downgrade SuperToken to ERC20.
* @dev It will call transfer to send tokens
* @param amount Number of tokens to be downgraded
*/
function downgrade(uint256 amount) external;
/**
* @dev Token downgrade event
* @param account Account whose tokens are upgraded
* @param amount Amount of tokens downgraded
*/
event TokenDowngraded(
address indexed account,
uint256 amount
);
/**************************************************************************
* Batch Operations
*************************************************************************/
/**
* @dev Perform ERC20 approve by host contract.
* @param account The account owner to be approved.
* @param spender The spender of account owner's funds.
* @param amount Number of tokens to be approved.
*
* @custom:modifiers
* - onlyHost
*/
function operationApprove(
address account,
address spender,
uint256 amount
) external;
/**
* @dev Perform ERC20 transfer from by host contract.
* @param account The account to spend sender's funds.
* @param spender The account where the funds is sent from.
* @param recipient The recipient of thefunds.
* @param amount Number of tokens to be transferred.
*
* @custom:modifiers
* - onlyHost
*/
function operationTransferFrom(
address account,
address spender,
address recipient,
uint256 amount
) external;
/**
* @dev Upgrade ERC20 to SuperToken by host contract.
* @param account The account to be changed.
* @param amount Number of tokens to be upgraded (in 18 decimals)
*
* @custom:modifiers
* - onlyHost
*/
function operationUpgrade(address account, uint256 amount) external;
/**
* @dev Downgrade ERC20 to SuperToken by host contract.
* @param account The account to be changed.
* @param amount Number of tokens to be downgraded (in 18 decimals)
*
* @custom:modifiers
* - onlyHost
*/
function operationDowngrade(address account, uint256 amount) external;
/**************************************************************************
* Function modifiers for access control and parameter validations
*
* While they cannot be explicitly stated in function definitions, they are
* listed in function definition comments instead for clarity.
*
* NOTE: solidity-coverage not supporting it
*************************************************************************/
/// @dev The msg.sender must be the contract itself
//modifier onlySelf() virtual
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { IERC173 } from '../../interfaces/IERC173.sol';
import { AddressUtils } from '../../utils/AddressUtils.sol';
import { IOwnableInternal } from './IOwnableInternal.sol';
import { OwnableStorage } from './OwnableStorage.sol';
abstract contract OwnableInternal is IOwnableInternal {
using AddressUtils for address;
using OwnableStorage for OwnableStorage.Layout;
modifier onlyOwner() {
require(msg.sender == _owner(), 'Ownable: sender must be owner');
_;
}
modifier onlyTransitiveOwner() {
require(
msg.sender == _transitiveOwner(),
'Ownable: sender must be transitive owner'
);
_;
}
function _owner() internal view virtual returns (address) {
return OwnableStorage.layout().owner;
}
function _transitiveOwner() internal view virtual returns (address) {
address owner = _owner();
while (owner.isContract()) {
try IERC173(owner).owner() returns (address transitiveOwner) {
owner = transitiveOwner;
} catch {
return owner;
}
}
return owner;
}
function _transferOwnership(address account) internal virtual {
OwnableStorage.layout().setOwner(account);
emit OwnershipTransferred(msg.sender, account);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;
interface ICFABeneficiary {
/// @notice Get last deletion for sender
function getLastDeletion(address sender) external view returns (uint256);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
library OwnableStorage {
struct Layout {
address owner;
}
bytes32 internal constant STORAGE_SLOT =
keccak256('solidstate.contracts.storage.Ownable');
function layout() internal pure returns (Layout storage l) {
bytes32 slot = STORAGE_SLOT;
assembly {
l.slot := slot
}
}
function setOwner(Layout storage l, address owner) internal {
l.owner = owner;
}
}// SPDX-License-Identifier: AGPLv3
pragma solidity >= 0.8.0;
import {
ISuperfluid,
ISuperfluidToken
} from "../interfaces/superfluid/ISuperfluid.sol";
import {
IConstantFlowAgreementV1
} from "../interfaces/agreements/IConstantFlowAgreementV1.sol";
/**
* @title Constant flow agreement v1 library
* @author Superfluid
* @dev for working with the constant flow agreement within solidity
* @dev the first set of functions are each for callAgreement()
* @dev the second set of functions are each for use in callAgreementWithContext()
*/
library CFAv1Library {
/**
* @dev Initialization data
* @param host Superfluid host for calling agreements
* @param cfa Constant Flow Agreement contract
*/
struct InitData {
ISuperfluid host;
IConstantFlowAgreementV1 cfa;
}
/**
* @dev Create flow without userData
* @param cfaLibrary The cfaLibrary storage variable
* @param receiver The receiver of the flow
* @param token The token to flow
* @param flowRate The desired flowRate
*/
function createFlow(
InitData storage cfaLibrary,
address receiver,
ISuperfluidToken token,
int96 flowRate
) internal {
createFlow(cfaLibrary, receiver, token, flowRate, new bytes(0));
}
/**
* @dev Create flow with userData
* @param cfaLibrary The cfaLibrary storage variable
* @param receiver The receiver of the flow
* @param token The token to flow
* @param flowRate The desired flowRate
* @param userData The user provided data
*/
function createFlow(
InitData storage cfaLibrary,
address receiver,
ISuperfluidToken token,
int96 flowRate,
bytes memory userData
) internal {
cfaLibrary.host.callAgreement(
cfaLibrary.cfa,
abi.encodeCall(
cfaLibrary.cfa.createFlow,
(
token,
receiver,
flowRate,
new bytes(0) // placeholder
)
),
userData
);
}
/**
* @dev Update flow without userData
* @param cfaLibrary The cfaLibrary storage variable
* @param receiver The receiver of the flow
* @param token The token to flow
* @param flowRate The desired flowRate
*/
function updateFlow(
InitData storage cfaLibrary,
address receiver,
ISuperfluidToken token,
int96 flowRate
) internal {
updateFlow(cfaLibrary, receiver, token, flowRate, new bytes(0));
}
/**
* @dev Update flow with userData
* @param cfaLibrary The cfaLibrary storage variable
* @param receiver The receiver of the flow
* @param token The token to flow
* @param flowRate The desired flowRate
* @param userData The user provided data
*/
function updateFlow(
InitData storage cfaLibrary,
address receiver,
ISuperfluidToken token,
int96 flowRate,
bytes memory userData
) internal {
cfaLibrary.host.callAgreement(
cfaLibrary.cfa,
abi.encodeCall(
cfaLibrary.cfa.updateFlow,
(
token,
receiver,
flowRate,
new bytes(0) // placeholder
)
),
userData
);
}
/**
* @dev Delete flow without userData
* @param cfaLibrary The cfaLibrary storage variable
* @param sender The sender of the flow
* @param receiver The receiver of the flow
* @param token The token to flow
*/
function deleteFlow(
InitData storage cfaLibrary,
address sender,
address receiver,
ISuperfluidToken token
) internal {
deleteFlow(cfaLibrary, sender, receiver, token, new bytes(0));
}
/**
* @dev Delete flow with userData
* @param cfaLibrary The cfaLibrary storage variable
* @param sender The sender of the flow
* @param receiver The receiver of the flow
* @param token The token to flow
* @param userData The user provided data
*/
function deleteFlow(
InitData storage cfaLibrary,
address sender,
address receiver,
ISuperfluidToken token,
bytes memory userData
) internal {
cfaLibrary.host.callAgreement(
cfaLibrary.cfa,
abi.encodeCall(
cfaLibrary.cfa.deleteFlow,
(
token,
sender,
receiver,
new bytes(0) // placeholder
)
),
userData
);
}
/**
* @dev Create flow with context and userData
* @param cfaLibrary The cfaLibrary storage variable
* @param ctx Context bytes (see ISuperfluid.sol for Context struct)
* @param receiver The receiver of the flow
* @param token The token to flow
* @param flowRate The desired flowRate
*/
function createFlowWithCtx(
InitData storage cfaLibrary,
bytes memory ctx,
address receiver,
ISuperfluidToken token,
int96 flowRate
) internal returns (bytes memory newCtx) {
return createFlowWithCtx(cfaLibrary, ctx, receiver, token, flowRate, new bytes(0));
}
/**
* @dev Create flow with context and userData
* @param cfaLibrary The cfaLibrary storage variable
* @param ctx Context bytes (see ISuperfluid.sol for Context struct)
* @param receiver The receiver of the flow
* @param token The token to flow
* @param flowRate The desired flowRate
* @param userData The user provided data
*/
function createFlowWithCtx(
InitData storage cfaLibrary,
bytes memory ctx,
address receiver,
ISuperfluidToken token,
int96 flowRate,
bytes memory userData
) internal returns (bytes memory newCtx) {
(newCtx, ) = cfaLibrary.host.callAgreementWithContext(
cfaLibrary.cfa,
abi.encodeCall(
cfaLibrary.cfa.createFlow,
(
token,
receiver,
flowRate,
new bytes(0) // placeholder
)
),
userData,
ctx
);
}
/**
* @dev Update flow with context
* @param cfaLibrary The cfaLibrary storage variable
* @param ctx Context bytes (see ISuperfluid.sol for Context struct)
* @param receiver The receiver of the flow
* @param token The token to flow
* @param flowRate The desired flowRate
*/
function updateFlowWithCtx(
InitData storage cfaLibrary,
bytes memory ctx,
address receiver,
ISuperfluidToken token,
int96 flowRate
) internal returns (bytes memory newCtx) {
return updateFlowWithCtx(cfaLibrary, ctx, receiver, token, flowRate, new bytes(0));
}
/**
* @dev Update flow with context and userData
* @param cfaLibrary The cfaLibrary storage variable
* @param ctx Context bytes (see ISuperfluid.sol for Context struct)
* @param receiver The receiver of the flow
* @param token The token to flow
* @param flowRate The desired flowRate
* @param userData The user provided data
*/
function updateFlowWithCtx(
InitData storage cfaLibrary,
bytes memory ctx,
address receiver,
ISuperfluidToken token,
int96 flowRate,
bytes memory userData
) internal returns (bytes memory newCtx) {
(newCtx, ) = cfaLibrary.host.callAgreementWithContext(
cfaLibrary.cfa,
abi.encodeCall(
cfaLibrary.cfa.updateFlow,
(
token,
receiver,
flowRate,
new bytes(0) // placeholder
)
),
userData,
ctx
);
}
/**
* @dev Delete flow with context
* @param cfaLibrary The cfaLibrary storage variable
* @param ctx Context bytes (see ISuperfluid.sol for Context struct)
* @param sender The sender of the flow
* @param receiver The receiver of the flow
* @param token The token to flow
*/
function deleteFlowWithCtx(
InitData storage cfaLibrary,
bytes memory ctx,
address sender,
address receiver,
ISuperfluidToken token
) internal returns (bytes memory newCtx) {
return deleteFlowWithCtx(cfaLibrary, ctx, sender, receiver, token, new bytes(0));
}
/**
* @dev Delete flow with context and userData
* @param cfaLibrary The cfaLibrary storage variable
* @param ctx Context bytes (see ISuperfluid.sol for Context struct)
* @param sender The sender of the flow
* @param receiver The receiver of the flow
* @param token The token to flow
* @param userData The user provided data
*/
function deleteFlowWithCtx(
InitData storage cfaLibrary,
bytes memory ctx,
address sender,
address receiver,
ISuperfluidToken token,
bytes memory userData
) internal returns (bytes memory newCtx) {
(newCtx, ) = cfaLibrary.host.callAgreementWithContext(
cfaLibrary.cfa,
abi.encodeCall(
cfaLibrary.cfa.deleteFlow,
(
token,
sender,
receiver,
new bytes(0) // placeholder
)
),
userData,
ctx
);
}
/**
* @dev Creates flow as an operator without userData
* @param cfaLibrary The cfaLibrary storage variable
* @param sender The sender of the flow
* @param receiver The receiver of the flow
* @param token The token to flow
* @param flowRate The desired flowRate
*/
function createFlowByOperator(
InitData storage cfaLibrary,
address sender,
address receiver,
ISuperfluidToken token,
int96 flowRate
) internal returns (bytes memory newCtx) {
return createFlowByOperator(cfaLibrary, sender, receiver, token, flowRate, new bytes(0));
}
/**
* @dev Creates flow as an operator with userData
* @param cfaLibrary The cfaLibrary storage variable
* @param sender The sender of the flow
* @param receiver The receiver of the flow
* @param token The token to flow
* @param flowRate The desired flowRate
* @param userData The user provided data
*/
function createFlowByOperator(
InitData storage cfaLibrary,
address sender,
address receiver,
ISuperfluidToken token,
int96 flowRate,
bytes memory userData
) internal returns (bytes memory newCtx) {
return cfaLibrary.host.callAgreement(
cfaLibrary.cfa,
abi.encodeCall(
cfaLibrary.cfa.createFlowByOperator,
(
token,
sender,
receiver,
flowRate,
new bytes(0) // placeholder
)
),
userData
);
}
/**
* @dev Creates flow as an operator without userData with context
* @param cfaLibrary The cfaLibrary storage variable
* @param ctx Context bytes (see ISuperfluid.sol for Context struct)
* @param sender The sender of the flow
* @param receiver The receiver of the flow
* @param token The token to flow
* @param flowRate The desired flowRate
*/
function createFlowByOperatorWithCtx(
InitData storage cfaLibrary,
bytes memory ctx,
address sender,
address receiver,
ISuperfluidToken token,
int96 flowRate
) internal returns (bytes memory newCtx) {
return createFlowByOperatorWithCtx(
cfaLibrary,
ctx,
sender,
receiver,
token,
flowRate,
new bytes(0)
);
}
/**
* @dev Creates flow as an operator with userData and context
* @param cfaLibrary The cfaLibrary storage variable
* @param ctx Context bytes (see ISuperfluid.sol for Context struct)
* @param sender The sender of the flow
* @param receiver The receiver of the flow
* @param token The token to flow
* @param flowRate The desired flowRate
* @param userData The user provided data
*/
function createFlowByOperatorWithCtx(
InitData storage cfaLibrary,
bytes memory ctx,
address sender,
address receiver,
ISuperfluidToken token,
int96 flowRate,
bytes memory userData
) internal returns (bytes memory newCtx) {
(newCtx, ) = cfaLibrary.host.callAgreementWithContext(
cfaLibrary.cfa,
abi.encodeCall(
cfaLibrary.cfa.createFlowByOperator,
(
token,
sender,
receiver,
flowRate,
new bytes(0) // placeholder
)
),
userData,
ctx
);
}
/**
* @dev Updates a flow as an operator without userData
* @param cfaLibrary The cfaLibrary storage variable
* @param sender The sender of the flow
* @param receiver The receiver of the flow
* @param token The token to flow
* @param flowRate The desired flowRate
*/
function updateFlowByOperator(
InitData storage cfaLibrary,
address sender,
address receiver,
ISuperfluidToken token,
int96 flowRate
) internal returns (bytes memory newCtx) {
return updateFlowByOperator(cfaLibrary, sender, receiver, token, flowRate, new bytes(0));
}
/**
* @dev Updates flow as an operator with userData
* @param cfaLibrary The cfaLibrary storage variable
* @param sender The sender of the flow
* @param receiver The receiver of the flow
* @param token The token to flow
* @param flowRate The desired flowRate
* @param userData The user provided data
*/
function updateFlowByOperator(
InitData storage cfaLibrary,
address sender,
address receiver,
ISuperfluidToken token,
int96 flowRate,
bytes memory userData
) internal returns (bytes memory newCtx) {
return cfaLibrary.host.callAgreement(
cfaLibrary.cfa,
abi.encodeCall(
cfaLibrary.cfa.updateFlowByOperator,
(
token,
sender,
receiver,
flowRate,
new bytes(0)
)
),
userData
);
}
/**
* @dev Updates a flow as an operator without userData with context
* @param cfaLibrary The cfaLibrary storage variable
* @param ctx Context bytes (see ISuperfluid.sol for Context struct)
* @param sender The sender of the flow
* @param receiver The receiver of the flow
* @param token The token to flow
* @param flowRate The desired flowRate
*/
function updateFlowByOperatorWithCtx(
InitData storage cfaLibrary,
bytes memory ctx,
address sender,
address receiver,
ISuperfluidToken token,
int96 flowRate
) internal returns (bytes memory newCtx) {
return updateFlowByOperatorWithCtx(
cfaLibrary,
ctx,
sender,
receiver,
token,
flowRate,
new bytes(0)
);
}
/**
* @dev Updates flow as an operator with userData and context
* @param cfaLibrary The cfaLibrary storage variable
* @param ctx Context bytes (see ISuperfluid.sol for Context struct)
* @param sender The sender of the flow
* @param receiver The receiver of the flow
* @param token The token to flow
* @param flowRate The desired flowRate
* @param userData The user provided data
*/
function updateFlowByOperatorWithCtx(
InitData storage cfaLibrary,
bytes memory ctx,
address sender,
address receiver,
ISuperfluidToken token,
int96 flowRate,
bytes memory userData
) internal returns (bytes memory newCtx) {
(newCtx, ) = cfaLibrary.host.callAgreementWithContext(
cfaLibrary.cfa,
abi.encodeCall(
cfaLibrary.cfa.updateFlowByOperator,
(
token,
sender,
receiver,
flowRate,
new bytes(0)
)
),
userData,
ctx
);
}
/**
* @dev Deletes a flow as an operator without userData
* @param cfaLibrary The cfaLibrary storage variable
* @param sender The sender of the flow
* @param receiver The receiver of the flow
* @param token The token to flow
*/
function deleteFlowByOperator(
InitData storage cfaLibrary,
address sender,
address receiver,
ISuperfluidToken token
) internal returns (bytes memory newCtx) {
return deleteFlowByOperator(cfaLibrary, sender, receiver, token, new bytes(0));
}
/**
* @dev Deletes a flow as an operator with userData
* @param cfaLibrary The cfaLibrary storage variable
* @param sender The sender of the flow
* @param receiver The receiver of the flow
* @param token The token to flow
* @param userData The user provided data
*/
function deleteFlowByOperator(
InitData storage cfaLibrary,
address sender,
address receiver,
ISuperfluidToken token,
bytes memory userData
) internal returns (bytes memory newCtx) {
return cfaLibrary.host.callAgreement(
cfaLibrary.cfa,
abi.encodeCall(
cfaLibrary.cfa.deleteFlowByOperator,
(
token,
sender,
receiver,
new bytes(0)
)
),
userData
);
}
/**
* @dev Deletes a flow as an operator without userData with context
* @param cfaLibrary The cfaLibrary storage variable
* @param ctx Context bytes (see ISuperfluid.sol for Context struct)
* @param sender The sender of the flow
* @param receiver The receiver of the flow
* @param token The token to flow
*/
function deleteFlowByOperatorWithCtx(
InitData storage cfaLibrary,
bytes memory ctx,
address sender,
address receiver,
ISuperfluidToken token
) internal returns (bytes memory newCtx) {
return deleteFlowByOperatorWithCtx(cfaLibrary, ctx, sender, receiver, token, new bytes(0));
}
/**
* @dev Deletes a flow as an operator with userData and context
* @param cfaLibrary The cfaLibrary storage variable
* @param ctx Context bytes (see ISuperfluid.sol for Context struct)
* @param sender The sender of the flow
* @param receiver The receiver of the flow
* @param token The token to flow
* @param userData The user provided data
*/
function deleteFlowByOperatorWithCtx(
InitData storage cfaLibrary,
bytes memory ctx,
address sender,
address receiver,
ISuperfluidToken token,
bytes memory userData
) internal returns (bytes memory newCtx) {
(newCtx, ) = cfaLibrary.host.callAgreementWithContext(
cfaLibrary.cfa,
abi.encodeCall(
cfaLibrary.cfa.deleteFlowByOperator,
(
token,
sender,
receiver,
new bytes(0)
)
),
userData,
ctx
);
}
/**
* @dev Updates the permissions of a flow operator
* @param cfaLibrary The cfaLibrary storage variable
* @param flowOperator The operator that can create/update/delete flows
* @param token The token of flows handled by the operator
* @param permissions The number of the permissions: create = 1; update = 2; delete = 4;
* To give multiple permissions, sum the above. create_delete = 5; create_update_delete = 7; etc
* @param flowRateAllowance The allowance for flow creation. Decremented as flowRate increases
*/
function updateFlowOperatorPermissions(
InitData storage cfaLibrary,
address flowOperator,
ISuperfluidToken token,
uint8 permissions,
int96 flowRateAllowance
) internal returns (bytes memory newCtx) {
return cfaLibrary.host.callAgreement(
cfaLibrary.cfa,
abi.encodeCall(
cfaLibrary.cfa.updateFlowOperatorPermissions,
(
token,
flowOperator,
permissions,
flowRateAllowance,
new bytes(0)
)
),
new bytes(0)
);
}
/**
* @dev Updates the permissions of a flow operator with context
* @param cfaLibrary The cfaLibrary storage variable
* @param ctx Context bytes (see ISuperfluid.sol for Context struct)
* @param flowOperator The operator that can create/update/delete flows
* @param token The token of flows handled by the operator
* @param permissions The number of the permissions: create = 1; update = 2; delete = 4;
* To give multiple permissions, sum the above. create_delete = 5; create_update_delete = 7; etc
* @param flowRateAllowance The allowance for flow creation. Decremented as flowRate increases
*/
function updateFlowOperatorPermissionsWithCtx(
InitData storage cfaLibrary,
bytes memory ctx,
address flowOperator,
ISuperfluidToken token,
uint8 permissions,
int96 flowRateAllowance
) internal returns (bytes memory newCtx) {
(newCtx, ) = cfaLibrary.host.callAgreementWithContext(
cfaLibrary.cfa,
abi.encodeCall(
cfaLibrary.cfa.updateFlowOperatorPermissions,
(
token,
flowOperator,
permissions,
flowRateAllowance,
new bytes(0)
)
),
new bytes(0),
ctx
);
}
/**
* @dev Grants full, unlimited permission to a flow operator
* @param cfaLibrary The cfaLibrary storage variable
* @param flowOperator The operator that can create/update/delete flows
* @param token The token of flows handled by the operator
*/
function authorizeFlowOperatorWithFullControl(
InitData storage cfaLibrary,
address flowOperator,
ISuperfluidToken token
) internal returns (bytes memory newCtx) {
return cfaLibrary.host.callAgreement(
cfaLibrary.cfa,
abi.encodeCall(
cfaLibrary.cfa.authorizeFlowOperatorWithFullControl,
(
token,
flowOperator,
new bytes(0)
)
),
new bytes(0)
);
}
/**
* @dev Grants full, unlimited permission to a flow operator with context
* @param cfaLibrary The cfaLibrary storage variable
* @param ctx Context bytes (see ISuperfluid.sol for Context struct)
* @param flowOperator The operator that can create/update/delete flows
* @param token The token of flows handled by the operator
*/
function authorizeFlowOperatorWithFullControlWithCtx(
InitData storage cfaLibrary,
bytes memory ctx,
address flowOperator,
ISuperfluidToken token
) internal returns (bytes memory newCtx) {
(newCtx, ) = cfaLibrary.host.callAgreementWithContext(
cfaLibrary.cfa,
abi.encodeCall(
cfaLibrary.cfa.authorizeFlowOperatorWithFullControl,
(
token,
flowOperator,
new bytes(0)
)
),
new bytes(0),
ctx
);
}
/**
* @dev Revokes all permissions from a flow operator
* @param cfaLibrary The cfaLibrary storage variable
* @param flowOperator The operator that can create/update/delete flows
* @param token The token of flows handled by the operator
*/
function revokeFlowOperatorWithFullControl(
InitData storage cfaLibrary,
address flowOperator,
ISuperfluidToken token
) internal returns (bytes memory newCtx) {
return cfaLibrary.host.callAgreement(
cfaLibrary.cfa,
abi.encodeCall(
cfaLibrary.cfa.revokeFlowOperatorWithFullControl,
(
token,
flowOperator,
new bytes(0)
)
),
new bytes(0)
);
}
/**
* @dev Revokes all permissions from a flow operator
* @param cfaLibrary The cfaLibrary storage variable
* @param ctx Context bytes (see ISuperfluid.sol for Context struct)
* @param flowOperator The operator that can create/update/delete flows
* @param token The token of flows handled by the operator
*/
function revokeFlowOperatorWithFullControlWithCtx(
InitData storage cfaLibrary,
bytes memory ctx,
address flowOperator,
ISuperfluidToken token
) internal returns (bytes memory newCtx) {
(newCtx, ) = cfaLibrary.host.callAgreementWithContext(
cfaLibrary.cfa,
abi.encodeCall(
cfaLibrary.cfa.revokeFlowOperatorWithFullControl,
(
token,
flowOperator,
new bytes(0)
)
),
new bytes(0),
ctx
);
}
}// SPDX-License-Identifier: AGPLv3
pragma solidity >= 0.8.0;
import { ISuperAgreement } from "./ISuperAgreement.sol";
import { ISuperToken } from "./ISuperToken.sol";
import { ISuperfluidToken } from "./ISuperfluidToken.sol";
import { ISuperfluid } from "./ISuperfluid.sol";
/**
* @title Superfluid governance interface
* @author Superfluid
*/
interface ISuperfluidGovernance {
/**
* @dev Replace the current governance with a new governance
*/
function replaceGovernance(
ISuperfluid host,
address newGov) external;
/**
* @dev Register a new agreement class
*/
function registerAgreementClass(
ISuperfluid host,
address agreementClass) external;
/**
* @dev Update logics of the contracts
*
* @custom:note
* - Because they might have inter-dependencies, it is good to have one single function to update them all
*/
function updateContracts(
ISuperfluid host,
address hostNewLogic,
address[] calldata agreementClassNewLogics,
address superTokenFactoryNewLogic
) external;
/**
* @dev Update supertoken logic contract to the latest that is managed by the super token factory
*/
function batchUpdateSuperTokenLogic(
ISuperfluid host,
ISuperToken[] calldata tokens) external;
/**
* @dev Set configuration as address value
*/
function setConfig(
ISuperfluid host,
ISuperfluidToken superToken,
bytes32 key,
address value
) external;
/**
* @dev Set configuration as uint256 value
*/
function setConfig(
ISuperfluid host,
ISuperfluidToken superToken,
bytes32 key,
uint256 value
) external;
/**
* @dev Clear configuration
*/
function clearConfig(
ISuperfluid host,
ISuperfluidToken superToken,
bytes32 key
) external;
/**
* @dev Get configuration as address value
*/
function getConfigAsAddress(
ISuperfluid host,
ISuperfluidToken superToken,
bytes32 key) external view returns (address value);
/**
* @dev Get configuration as uint256 value
*/
function getConfigAsUint256(
ISuperfluid host,
ISuperfluidToken superToken,
bytes32 key) external view returns (uint256 value);
}// SPDX-License-Identifier: AGPLv3
pragma solidity >= 0.8.0;
import { ISuperAgreement } from "./ISuperAgreement.sol";
/**
* @title Superfluid token interface
* @author Superfluid
*/
interface ISuperfluidToken {
/**************************************************************************
* Basic information
*************************************************************************/
/**
* @dev Get superfluid host contract address
*/
function getHost() external view returns(address host);
/**
* @dev Encoded liquidation type data mainly used for handling stack to deep errors
*
* @custom:note
* - version: 1
* - liquidationType key:
* - 0 = reward account receives reward (PIC period)
* - 1 = liquidator account receives reward (Pleb period)
* - 2 = liquidator account receives reward (Pirate period/bailout)
*/
struct LiquidationTypeData {
uint256 version;
uint8 liquidationType;
}
/**************************************************************************
* Real-time balance functions
*************************************************************************/
/**
* @dev Calculate the real balance of a user, taking in consideration all agreements of the account
* @param account for the query
* @param timestamp Time of balance
* @return availableBalance Real-time balance
* @return deposit Account deposit
* @return owedDeposit Account owed Deposit
*/
function realtimeBalanceOf(
address account,
uint256 timestamp
)
external view
returns (
int256 availableBalance,
uint256 deposit,
uint256 owedDeposit);
/**
* @notice Calculate the realtime balance given the current host.getNow() value
* @dev realtimeBalanceOf with timestamp equals to block timestamp
* @param account for the query
* @return availableBalance Real-time balance
* @return deposit Account deposit
* @return owedDeposit Account owed Deposit
*/
function realtimeBalanceOfNow(
address account
)
external view
returns (
int256 availableBalance,
uint256 deposit,
uint256 owedDeposit,
uint256 timestamp);
/**
* @notice Check if account is critical
* @dev A critical account is when availableBalance < 0
* @param account The account to check
* @param timestamp The time we'd like to check if the account is critical (should use future)
* @return isCritical Whether the account is critical
*/
function isAccountCritical(
address account,
uint256 timestamp
)
external view
returns(bool isCritical);
/**
* @notice Check if account is critical now (current host.getNow())
* @dev A critical account is when availableBalance < 0
* @param account The account to check
* @return isCritical Whether the account is critical
*/
function isAccountCriticalNow(
address account
)
external view
returns(bool isCritical);
/**
* @notice Check if account is solvent
* @dev An account is insolvent when the sum of deposits for a token can't cover the negative availableBalance
* @param account The account to check
* @param timestamp The time we'd like to check if the account is solvent (should use future)
* @return isSolvent True if the account is solvent, false otherwise
*/
function isAccountSolvent(
address account,
uint256 timestamp
)
external view
returns(bool isSolvent);
/**
* @notice Check if account is solvent now
* @dev An account is insolvent when the sum of deposits for a token can't cover the negative availableBalance
* @param account The account to check
* @return isSolvent True if the account is solvent, false otherwise
*/
function isAccountSolventNow(
address account
)
external view
returns(bool isSolvent);
/**
* @notice Get a list of agreements that is active for the account
* @dev An active agreement is one that has state for the account
* @param account Account to query
* @return activeAgreements List of accounts that have non-zero states for the account
*/
function getAccountActiveAgreements(address account)
external view
returns(ISuperAgreement[] memory activeAgreements);
/**************************************************************************
* Super Agreement hosting functions
*************************************************************************/
/**
* @dev Create a new agreement
* @param id Agreement ID
* @param data Agreement data
*/
function createAgreement(
bytes32 id,
bytes32[] calldata data
)
external;
/**
* @dev Agreement created event
* @param agreementClass Contract address of the agreement
* @param id Agreement ID
* @param data Agreement data
*/
event AgreementCreated(
address indexed agreementClass,
bytes32 id,
bytes32[] data
);
/**
* @dev Get data of the agreement
* @param agreementClass Contract address of the agreement
* @param id Agreement ID
* @return data Data of the agreement
*/
function getAgreementData(
address agreementClass,
bytes32 id,
uint dataLength
)
external view
returns(bytes32[] memory data);
/**
* @dev Create a new agreement
* @param id Agreement ID
* @param data Agreement data
*/
function updateAgreementData(
bytes32 id,
bytes32[] calldata data
)
external;
/**
* @dev Agreement updated event
* @param agreementClass Contract address of the agreement
* @param id Agreement ID
* @param data Agreement data
*/
event AgreementUpdated(
address indexed agreementClass,
bytes32 id,
bytes32[] data
);
/**
* @dev Close the agreement
* @param id Agreement ID
*/
function terminateAgreement(
bytes32 id,
uint dataLength
)
external;
/**
* @dev Agreement terminated event
* @param agreementClass Contract address of the agreement
* @param id Agreement ID
*/
event AgreementTerminated(
address indexed agreementClass,
bytes32 id
);
/**
* @dev Update agreement state slot
* @param account Account to be updated
*
* @custom:note
* - To clear the storage out, provide zero-ed array of intended length
*/
function updateAgreementStateSlot(
address account,
uint256 slotId,
bytes32[] calldata slotData
)
external;
/**
* @dev Agreement account state updated event
* @param agreementClass Contract address of the agreement
* @param account Account updated
* @param slotId slot id of the agreement state
*/
event AgreementStateUpdated(
address indexed agreementClass,
address indexed account,
uint256 slotId
);
/**
* @dev Get data of the slot of the state of an agreement
* @param agreementClass Contract address of the agreement
* @param account Account to query
* @param slotId slot id of the state
* @param dataLength length of the state data
*/
function getAgreementStateSlot(
address agreementClass,
address account,
uint256 slotId,
uint dataLength
)
external view
returns (bytes32[] memory slotData);
/**
* @notice Settle balance from an account by the agreement
* @dev The agreement needs to make sure that the balance delta is balanced afterwards
* @param account Account to query.
* @param delta Amount of balance delta to be settled
*
* @custom:modifiers
* - onlyAgreement
*/
function settleBalance(
address account,
int256 delta
)
external;
/**
* @dev Make liquidation payouts (v2)
* @param id Agreement ID
* @param liquidationTypeData Data regarding the version of the liquidation schema and the type
* @param liquidatorAccount Address of the executor of the liquidation
* @param useDefaultRewardAccount Whether or not the default reward account receives the rewardAmount
* @param targetAccount Account to be liquidated
* @param rewardAmount The amount the rewarded account will receive
* @param targetAccountBalanceDelta The delta amount the target account balance should change by
*
* @custom:note
* - If a bailout is required (bailoutAmount > 0)
* - the actual reward (single deposit) goes to the executor,
* - while the reward account becomes the bailout account
* - total bailout include: bailout amount + reward amount
* - the targetAccount will be bailed out
* - If a bailout is not required
* - the targetAccount will pay the rewardAmount
* - the liquidator (reward account in PIC period) will receive the rewardAmount
*
* @custom:modifiers
* - onlyAgreement
*/
function makeLiquidationPayoutsV2
(
bytes32 id,
bytes memory liquidationTypeData,
address liquidatorAccount,
bool useDefaultRewardAccount,
address targetAccount,
uint256 rewardAmount,
int256 targetAccountBalanceDelta
) external;
/**
* @dev Agreement liquidation event v2 (including agent account)
* @param agreementClass Contract address of the agreement
* @param id Agreement ID
* @param liquidatorAccount Address of the executor of the liquidation
* @param targetAccount Account of the stream sender
* @param rewardAmountReceiver Account that collects the reward or bails out insolvent accounts
* @param rewardAmount The amount the reward recipient account balance should change by
* @param targetAccountBalanceDelta The amount the sender account balance should change by
* @param liquidationTypeData The encoded liquidation type data including the version (how to decode)
*
* @custom:note
* Reward account rule:
* - if the agreement is liquidated during the PIC period
* - the rewardAmountReceiver will get the rewardAmount (remaining deposit), regardless of the liquidatorAccount
* - the targetAccount will pay for the rewardAmount
* - if the agreement is liquidated after the PIC period AND the targetAccount is solvent
* - the rewardAmountReceiver will get the rewardAmount (remaining deposit)
* - the targetAccount will pay for the rewardAmount
* - if the targetAccount is insolvent
* - the liquidatorAccount will get the rewardAmount (single deposit)
* - the default reward account (governance) will pay for both the rewardAmount and bailoutAmount
* - the targetAccount will receive the bailoutAmount
*/
event AgreementLiquidatedV2(
address indexed agreementClass,
bytes32 id,
address indexed liquidatorAccount,
address indexed targetAccount,
address rewardAmountReceiver,
uint256 rewardAmount,
int256 targetAccountBalanceDelta,
bytes liquidationTypeData
);
/**************************************************************************
* Function modifiers for access control and parameter validations
*
* While they cannot be explicitly stated in function definitions, they are
* listed in function definition comments instead for clarity.
*
* NOTE: solidity-coverage not supporting it
*************************************************************************/
/// @dev The msg.sender must be host contract
//modifier onlyHost() virtual;
/// @dev The msg.sender must be a listed agreement.
//modifier onlyAgreement() virtual;
/**************************************************************************
* DEPRECATED
*************************************************************************/
/**
* @dev Agreement liquidation event (DEPRECATED BY AgreementLiquidatedBy)
* @param agreementClass Contract address of the agreement
* @param id Agreement ID
* @param penaltyAccount Account of the agreement to be penalized
* @param rewardAccount Account that collect the reward
* @param rewardAmount Amount of liquidation reward
*
* @custom:deprecated Use AgreementLiquidatedV2 instead
*/
event AgreementLiquidated(
address indexed agreementClass,
bytes32 id,
address indexed penaltyAccount,
address indexed rewardAccount,
uint256 rewardAmount
);
/**
* @dev System bailout occurred (DEPRECATED BY AgreementLiquidatedBy)
* @param bailoutAccount Account that bailout the penalty account
* @param bailoutAmount Amount of account bailout
*
* @custom:deprecated Use AgreementLiquidatedV2 instead
*/
event Bailout(
address indexed bailoutAccount,
uint256 bailoutAmount
);
/**
* @dev Agreement liquidation event (DEPRECATED BY AgreementLiquidatedV2)
* @param liquidatorAccount Account of the agent that performed the liquidation.
* @param agreementClass Contract address of the agreement
* @param id Agreement ID
* @param penaltyAccount Account of the agreement to be penalized
* @param bondAccount Account that collect the reward or bailout accounts
* @param rewardAmount Amount of liquidation reward
* @param bailoutAmount Amount of liquidation bailouot
*
* @custom:deprecated Use AgreementLiquidatedV2 instead
*
* @custom:note
* Reward account rule:
* - if bailout is equal to 0, then
* - the bondAccount will get the rewardAmount,
* - the penaltyAccount will pay for the rewardAmount.
* - if bailout is larger than 0, then
* - the liquidatorAccount will get the rewardAmouont,
* - the bondAccount will pay for both the rewardAmount and bailoutAmount,
* - the penaltyAccount will pay for the rewardAmount while get the bailoutAmount.
*/
event AgreementLiquidatedBy(
address liquidatorAccount,
address indexed agreementClass,
bytes32 id,
address indexed penaltyAccount,
address indexed bondAccount,
uint256 rewardAmount,
uint256 bailoutAmount
);
}// SPDX-License-Identifier: AGPLv3
pragma solidity >= 0.8.0;
import { ISuperToken } from "./ISuperToken.sol";
import {
IERC20,
ERC20WithTokenInfo
} from "../tokens/ERC20WithTokenInfo.sol";
/**
* @title Super token factory interface
* @author Superfluid
*/
interface ISuperTokenFactory {
/**
* @dev Get superfluid host contract address
*/
function getHost() external view returns(address host);
/// @dev Initialize the contract
function initialize() external;
/**
* @dev Get the current super token logic used by the factory
*/
function getSuperTokenLogic() external view returns (ISuperToken superToken);
/**
* @dev Upgradability modes
*/
enum Upgradability {
/// Non upgradable super token, `host.updateSuperTokenLogic` will revert
NON_UPGRADABLE,
/// Upgradable through `host.updateSuperTokenLogic` operation
SEMI_UPGRADABLE,
/// Always using the latest super token logic
FULL_UPGRADABE
}
/**
* @dev Create new super token wrapper for the underlying ERC20 token
* @param underlyingToken Underlying ERC20 token
* @param underlyingDecimals Underlying token decimals
* @param upgradability Upgradability mode
* @param name Super token name
* @param symbol Super token symbol
*/
function createERC20Wrapper(
IERC20 underlyingToken,
uint8 underlyingDecimals,
Upgradability upgradability,
string calldata name,
string calldata symbol
)
external
returns (ISuperToken superToken);
/**
* @dev Create new super token wrapper for the underlying ERC20 token with extra token info
* @param underlyingToken Underlying ERC20 token
* @param upgradability Upgradability mode
* @param name Super token name
* @param symbol Super token symbol
*
* NOTE:
* - It assumes token provide the .decimals() function
*/
function createERC20Wrapper(
ERC20WithTokenInfo underlyingToken,
Upgradability upgradability,
string calldata name,
string calldata symbol
)
external
returns (ISuperToken superToken);
function initializeCustomSuperToken(
address customSuperTokenProxy
)
external;
/**
* @dev Super token logic created event
* @param tokenLogic Token logic address
*/
event SuperTokenLogicCreated(ISuperToken indexed tokenLogic);
/**
* @dev Super token created event
* @param token Newly created super token address
*/
event SuperTokenCreated(ISuperToken indexed token);
/**
* @dev Custom super token created event
* @param token Newly created custom super token address
*/
event CustomSuperTokenCreated(ISuperToken indexed token);
}// SPDX-License-Identifier: AGPLv3
pragma solidity >= 0.8.0;
import { ISuperfluidToken } from "./ISuperfluidToken.sol";
/**
* @title Super agreement interface
* @author Superfluid
*/
interface ISuperAgreement {
/**
* @dev Get the type of the agreement class
*/
function agreementType() external view returns (bytes32);
/**
* @dev Calculate the real-time balance for the account of this agreement class
* @param account Account the state belongs to
* @param time Time used for the calculation
* @return dynamicBalance Dynamic balance portion of real-time balance of this agreement
* @return deposit Account deposit amount of this agreement
* @return owedDeposit Account owed deposit amount of this agreement
*/
function realtimeBalanceOf(
ISuperfluidToken token,
address account,
uint256 time
)
external
view
returns (
int256 dynamicBalance,
uint256 deposit,
uint256 owedDeposit
);
}// SPDX-License-Identifier: AGPLv3
pragma solidity >= 0.8.0;
import { ISuperToken } from "./ISuperToken.sol";
/**
* @title SuperApp interface
* @author Superfluid
* @dev Be aware of the app being jailed, when the word permitted is used.
*/
interface ISuperApp {
/**
* @dev Callback before a new agreement is created.
* @param superToken The super token used for the agreement.
* @param agreementClass The agreement class address.
* @param agreementId The agreementId
* @param agreementData The agreement data (non-compressed)
* @param ctx The context data.
* @return cbdata A free format in memory data the app can use to pass
* arbitary information to the after-hook callback.
*
* @custom:note
* - It will be invoked with `staticcall`, no state changes are permitted.
* - Only revert with a "reason" is permitted.
*/
function beforeAgreementCreated(
ISuperToken superToken,
address agreementClass,
bytes32 agreementId,
bytes calldata agreementData,
bytes calldata ctx
)
external
view
returns (bytes memory cbdata);
/**
* @dev Callback after a new agreement is created.
* @param superToken The super token used for the agreement.
* @param agreementClass The agreement class address.
* @param agreementId The agreementId
* @param agreementData The agreement data (non-compressed)
* @param cbdata The data returned from the before-hook callback.
* @param ctx The context data.
* @return newCtx The current context of the transaction.
*
* @custom:note
* - State changes is permitted.
* - Only revert with a "reason" is permitted.
*/
function afterAgreementCreated(
ISuperToken superToken,
address agreementClass,
bytes32 agreementId,
bytes calldata agreementData,
bytes calldata cbdata,
bytes calldata ctx
)
external
returns (bytes memory newCtx);
/**
* @dev Callback before a new agreement is updated.
* @param superToken The super token used for the agreement.
* @param agreementClass The agreement class address.
* @param agreementId The agreementId
* @param agreementData The agreement data (non-compressed)
* @param ctx The context data.
* @return cbdata A free format in memory data the app can use to pass
* arbitary information to the after-hook callback.
*
* @custom:note
* - It will be invoked with `staticcall`, no state changes are permitted.
* - Only revert with a "reason" is permitted.
*/
function beforeAgreementUpdated(
ISuperToken superToken,
address agreementClass,
bytes32 agreementId,
bytes calldata agreementData,
bytes calldata ctx
)
external
view
returns (bytes memory cbdata);
/**
* @dev Callback after a new agreement is updated.
* @param superToken The super token used for the agreement.
* @param agreementClass The agreement class address.
* @param agreementId The agreementId
* @param agreementData The agreement data (non-compressed)
* @param cbdata The data returned from the before-hook callback.
* @param ctx The context data.
* @return newCtx The current context of the transaction.
*
* @custom:note
* - State changes is permitted.
* - Only revert with a "reason" is permitted.
*/
function afterAgreementUpdated(
ISuperToken superToken,
address agreementClass,
bytes32 agreementId,
bytes calldata agreementData,
bytes calldata cbdata,
bytes calldata ctx
)
external
returns (bytes memory newCtx);
/**
* @dev Callback before a new agreement is terminated.
* @param superToken The super token used for the agreement.
* @param agreementClass The agreement class address.
* @param agreementId The agreementId
* @param agreementData The agreement data (non-compressed)
* @param ctx The context data.
* @return cbdata A free format in memory data the app can use to pass arbitary information to the after-hook callback.
*
* @custom:note
* - It will be invoked with `staticcall`, no state changes are permitted.
* - Revert is not permitted.
*/
function beforeAgreementTerminated(
ISuperToken superToken,
address agreementClass,
bytes32 agreementId,
bytes calldata agreementData,
bytes calldata ctx
)
external
view
returns (bytes memory cbdata);
/**
* @dev Callback after a new agreement is terminated.
* @param superToken The super token used for the agreement.
* @param agreementClass The agreement class address.
* @param agreementId The agreementId
* @param agreementData The agreement data (non-compressed)
* @param cbdata The data returned from the before-hook callback.
* @param ctx The context data.
* @return newCtx The current context of the transaction.
*
* @custom:note
* - State changes is permitted.
* - Revert is not permitted.
*/
function afterAgreementTerminated(
ISuperToken superToken,
address agreementClass,
bytes32 agreementId,
bytes calldata agreementData,
bytes calldata cbdata,
bytes calldata ctx
)
external
returns (bytes memory newCtx);
}// SPDX-License-Identifier: AGPLv3
pragma solidity >= 0.8.0;
/**
* @title Super app definitions library
* @author Superfluid
*/
library SuperAppDefinitions {
/**************************************************************************
/ App manifest config word
/**************************************************************************/
/*
* App level is a way to allow the app to whitelist what other app it can
* interact with (aka. composite app feature).
*
* For more details, refer to the technical paper of superfluid protocol.
*/
uint256 constant internal APP_LEVEL_MASK = 0xFF;
// The app is at the final level, hence it doesn't want to interact with any other app
uint256 constant internal APP_LEVEL_FINAL = 1 << 0;
// The app is at the second level, it may interact with other final level apps if whitelisted
uint256 constant internal APP_LEVEL_SECOND = 1 << 1;
function getAppLevel(uint256 configWord) internal pure returns (uint8) {
return uint8(configWord & APP_LEVEL_MASK);
}
uint256 constant internal APP_JAIL_BIT = 1 << 15;
function isAppJailed(uint256 configWord) internal pure returns (bool) {
return (configWord & SuperAppDefinitions.APP_JAIL_BIT) > 0;
}
/**************************************************************************
/ Callback implementation bit masks
/**************************************************************************/
uint256 constant internal AGREEMENT_CALLBACK_NOOP_BITMASKS = 0xFF << 32;
uint256 constant internal BEFORE_AGREEMENT_CREATED_NOOP = 1 << (32 + 0);
uint256 constant internal AFTER_AGREEMENT_CREATED_NOOP = 1 << (32 + 1);
uint256 constant internal BEFORE_AGREEMENT_UPDATED_NOOP = 1 << (32 + 2);
uint256 constant internal AFTER_AGREEMENT_UPDATED_NOOP = 1 << (32 + 3);
uint256 constant internal BEFORE_AGREEMENT_TERMINATED_NOOP = 1 << (32 + 4);
uint256 constant internal AFTER_AGREEMENT_TERMINATED_NOOP = 1 << (32 + 5);
/**************************************************************************
/ App Jail Reasons
/**************************************************************************/
uint256 constant internal APP_RULE_REGISTRATION_ONLY_IN_CONSTRUCTOR = 1;
uint256 constant internal APP_RULE_NO_REGISTRATION_FOR_EOA = 2;
uint256 constant internal APP_RULE_NO_REVERT_ON_TERMINATION_CALLBACK = 10;
uint256 constant internal APP_RULE_NO_CRITICAL_SENDER_ACCOUNT = 11;
uint256 constant internal APP_RULE_NO_CRITICAL_RECEIVER_ACCOUNT = 12;
uint256 constant internal APP_RULE_CTX_IS_READONLY = 20;
uint256 constant internal APP_RULE_CTX_IS_NOT_CLEAN = 21;
uint256 constant internal APP_RULE_CTX_IS_MALFORMATED = 22;
uint256 constant internal APP_RULE_COMPOSITE_APP_IS_NOT_WHITELISTED = 30;
uint256 constant internal APP_RULE_COMPOSITE_APP_IS_JAILED = 31;
uint256 constant internal APP_RULE_MAX_APP_LEVEL_REACHED = 40;
// Validate configWord cleaness for future compatibility, or else may introduce undefined future behavior
function isConfigWordClean(uint256 configWord) internal pure returns (bool) {
return (configWord & ~(APP_LEVEL_MASK | APP_JAIL_BIT | AGREEMENT_CALLBACK_NOOP_BITMASKS)) == uint256(0);
}
}
/**
* @title Context definitions library
* @author Superfluid
*/
library ContextDefinitions {
/**************************************************************************
/ Call info
/**************************************************************************/
// app level
uint256 constant internal CALL_INFO_APP_LEVEL_MASK = 0xFF;
// call type
uint256 constant internal CALL_INFO_CALL_TYPE_SHIFT = 32;
uint256 constant internal CALL_INFO_CALL_TYPE_MASK = 0xF << CALL_INFO_CALL_TYPE_SHIFT;
uint8 constant internal CALL_INFO_CALL_TYPE_AGREEMENT = 1;
uint8 constant internal CALL_INFO_CALL_TYPE_APP_ACTION = 2;
uint8 constant internal CALL_INFO_CALL_TYPE_APP_CALLBACK = 3;
function decodeCallInfo(uint256 callInfo)
internal pure
returns (uint8 appLevel, uint8 callType)
{
appLevel = uint8(callInfo & CALL_INFO_APP_LEVEL_MASK);
callType = uint8((callInfo & CALL_INFO_CALL_TYPE_MASK) >> CALL_INFO_CALL_TYPE_SHIFT);
}
function encodeCallInfo(uint8 appLevel, uint8 callType)
internal pure
returns (uint256 callInfo)
{
return uint256(appLevel) | (uint256(callType) << CALL_INFO_CALL_TYPE_SHIFT);
}
}
/**
* @title Flow Operator definitions library
* @author Superfluid
*/
library FlowOperatorDefinitions {
uint8 constant internal AUTHORIZE_FLOW_OPERATOR_CREATE = uint8(1) << 0;
uint8 constant internal AUTHORIZE_FLOW_OPERATOR_UPDATE = uint8(1) << 1;
uint8 constant internal AUTHORIZE_FLOW_OPERATOR_DELETE = uint8(1) << 2;
uint8 constant internal AUTHORIZE_FULL_CONTROL =
AUTHORIZE_FLOW_OPERATOR_CREATE | AUTHORIZE_FLOW_OPERATOR_UPDATE | AUTHORIZE_FLOW_OPERATOR_DELETE;
uint8 constant internal REVOKE_FLOW_OPERATOR_CREATE = ~(uint8(1) << 0);
uint8 constant internal REVOKE_FLOW_OPERATOR_UPDATE = ~(uint8(1) << 1);
uint8 constant internal REVOKE_FLOW_OPERATOR_DELETE = ~(uint8(1) << 2);
function isPermissionsClean(uint8 permissions) internal pure returns (bool) {
return (
permissions & ~(AUTHORIZE_FLOW_OPERATOR_CREATE
| AUTHORIZE_FLOW_OPERATOR_UPDATE
| AUTHORIZE_FLOW_OPERATOR_DELETE)
) == uint8(0);
}
}
/**
* @title Batch operation library
* @author Superfluid
*/
library BatchOperation {
/**
* @dev ERC20.approve batch operation type
*
* Call spec:
* ISuperToken(target).operationApprove(
* abi.decode(data, (address spender, uint256 amount))
* )
*/
uint32 constant internal OPERATION_TYPE_ERC20_APPROVE = 1;
/**
* @dev ERC20.transferFrom batch operation type
*
* Call spec:
* ISuperToken(target).operationTransferFrom(
* abi.decode(data, (address sender, address recipient, uint256 amount)
* )
*/
uint32 constant internal OPERATION_TYPE_ERC20_TRANSFER_FROM = 2;
/**
* @dev SuperToken.upgrade batch operation type
*
* Call spec:
* ISuperToken(target).operationUpgrade(
* abi.decode(data, (uint256 amount)
* )
*/
uint32 constant internal OPERATION_TYPE_SUPERTOKEN_UPGRADE = 1 + 100;
/**
* @dev SuperToken.downgrade batch operation type
*
* Call spec:
* ISuperToken(target).operationDowngrade(
* abi.decode(data, (uint256 amount)
* )
*/
uint32 constant internal OPERATION_TYPE_SUPERTOKEN_DOWNGRADE = 2 + 100;
/**
* @dev Superfluid.callAgreement batch operation type
*
* Call spec:
* callAgreement(
* ISuperAgreement(target)),
* abi.decode(data, (bytes calldata, bytes userdata)
* )
*/
uint32 constant internal OPERATION_TYPE_SUPERFLUID_CALL_AGREEMENT = 1 + 200;
/**
* @dev Superfluid.callAppAction batch operation type
*
* Call spec:
* callAppAction(
* ISuperApp(target)),
* data
* )
*/
uint32 constant internal OPERATION_TYPE_SUPERFLUID_CALL_APP_ACTION = 2 + 200;
}
/**
* @title Superfluid governance configs library
* @author Superfluid
*/
library SuperfluidGovernanceConfigs {
bytes32 constant internal SUPERFLUID_REWARD_ADDRESS_CONFIG_KEY =
keccak256("org.superfluid-finance.superfluid.rewardAddress");
bytes32 constant internal CFAV1_PPP_CONFIG_KEY =
keccak256("org.superfluid-finance.agreements.ConstantFlowAgreement.v1.PPPConfiguration");
bytes32 constant internal SUPERTOKEN_MINIMUM_DEPOSIT_KEY =
keccak256("org.superfluid-finance.superfluid.superTokenMinimumDeposit");
function getTrustedForwarderConfigKey(address forwarder) internal pure returns (bytes32) {
return keccak256(abi.encode(
"org.superfluid-finance.superfluid.trustedForwarder",
forwarder));
}
function getAppRegistrationConfigKey(address deployer, string memory registrationKey) internal pure returns (bytes32) {
return keccak256(abi.encode(
"org.superfluid-finance.superfluid.appWhiteListing.registrationKey",
deployer,
registrationKey));
}
function getAppFactoryConfigKey(address factory) internal pure returns (bytes32) {
return keccak256(abi.encode(
"org.superfluid-finance.superfluid.appWhiteListing.factory",
factory));
}
function decodePPPConfig(uint256 pppConfig) internal pure returns (uint256 liquidationPeriod, uint256 patricianPeriod) {
liquidationPeriod = (pppConfig >> 32) & type(uint32).max;
patricianPeriod = pppConfig & type(uint32).max;
}
}// SPDX-License-Identifier: AGPLv3
pragma solidity >= 0.8.0;
/**
* @title ERC20 token info interface
* @author Superfluid
* @dev ERC20 standard interface does not specify these functions, but
* often the token implementations have them.
*/
interface TokenInfo {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() external view returns (string memory);
/**
* @dev 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: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() external view returns (uint8);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: 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
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC777/IERC777.sol)
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC777Token standard as defined in the EIP.
*
* This contract uses the
* https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let
* token holders and recipients react to token movements by using setting implementers
* for the associated interfaces in said registry. See {IERC1820Registry} and
* {ERC1820Implementer}.
*/
interface IERC777 {
/**
* @dev Emitted when `amount` tokens are created by `operator` and assigned to `to`.
*
* Note that some additional user `data` and `operatorData` can be logged in the event.
*/
event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData);
/**
* @dev Emitted when `operator` destroys `amount` tokens from `account`.
*
* Note that some additional user `data` and `operatorData` can be logged in the event.
*/
event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData);
/**
* @dev Emitted when `operator` is made operator for `tokenHolder`.
*/
event AuthorizedOperator(address indexed operator, address indexed tokenHolder);
/**
* @dev Emitted when `operator` is revoked its operator status for `tokenHolder`.
*/
event RevokedOperator(address indexed operator, address indexed tokenHolder);
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() external view returns (string memory);
/**
* @dev 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.
*
* For most token contracts, this value will equal 1.
*/
function granularity() external view returns (uint256);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by an account (`owner`).
*/
function balanceOf(address owner) external view returns (uint256);
/**
* @dev 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 `data` and empty
* `operatorData`. See {IERC777Sender} and {IERC777Recipient}.
*
* Emits a {Sent} event.
*
* 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}
* interface.
*/
function send(
address recipient,
uint256 amount,
bytes calldata data
) external;
/**
* @dev Destroys `amount` tokens from the caller's account, reducing the
* total supply.
*
* If a send hook is registered for the caller, the corresponding function
* will be called with `data` and empty `operatorData`. See {IERC777Sender}.
*
* Emits a {Burned} event.
*
* Requirements
*
* - the caller must have at least `amount` tokens.
*/
function burn(uint256 amount, bytes calldata data) external;
/**
* @dev 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} and {operatorBurn}.
*/
function isOperatorFor(address operator, address tokenHolder) external view returns (bool);
/**
* @dev Make an account an operator of the caller.
*
* See {isOperatorFor}.
*
* Emits an {AuthorizedOperator} event.
*
* Requirements
*
* - `operator` cannot be calling address.
*/
function authorizeOperator(address operator) external;
/**
* @dev Revoke an account's operator status for the caller.
*
* See {isOperatorFor} and {defaultOperators}.
*
* Emits a {RevokedOperator} event.
*
* Requirements
*
* - `operator` cannot be calling address.
*/
function revokeOperator(address operator) external;
/**
* @dev Returns the list of default operators. These accounts are operators
* for all token holders, even if {authorizeOperator} was never called on
* them.
*
* This list is immutable, but individual holders may revoke these via
* {revokeOperator}, in which case {isOperatorFor} will return false.
*/
function defaultOperators() external view returns (address[] memory);
/**
* @dev 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 `data` and
* `operatorData`. See {IERC777Sender} and {IERC777Recipient}.
*
* Emits a {Sent} event.
*
* 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}
* interface.
*/
function operatorSend(
address sender,
address recipient,
uint256 amount,
bytes calldata data,
bytes calldata operatorData
) external;
/**
* @dev 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 `data` and `operatorData`. See {IERC777Sender}.
*
* Emits a {Burned} event.
*
* Requirements
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
* - the caller must be an operator for `account`.
*/
function operatorBurn(
address account,
uint256 amount,
bytes calldata data,
bytes calldata operatorData
) external;
event Sent(
address indexed operator,
address indexed from,
address indexed to,
uint256 amount,
bytes data,
bytes operatorData
);
}// SPDX-License-Identifier: AGPLv3
pragma solidity >= 0.8.0;
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { TokenInfo } from "./TokenInfo.sol";
/**
* @title ERC20 token with token info interface
* @author Superfluid
* @dev Using abstract contract instead of interfaces because old solidity
* does not support interface inheriting other interfaces
* solhint-disable-next-line no-empty-blocks
*
*/
// solhint-disable-next-line no-empty-blocks
abstract contract ERC20WithTokenInfo is IERC20, TokenInfo {}// SPDX-License-Identifier: AGPLv3
pragma solidity >= 0.8.0;
import { ISuperAgreement } from "../superfluid/ISuperAgreement.sol";
import { ISuperfluidToken } from "../superfluid/ISuperfluidToken.sol";
/**
* @title Constant Flow Agreement interface
* @author Superfluid
*/
abstract contract IConstantFlowAgreementV1 is ISuperAgreement {
/// @dev ISuperAgreement.agreementType implementation
function agreementType() external override pure returns (bytes32) {
return keccak256("org.superfluid-finance.agreements.ConstantFlowAgreement.v1");
}
/**
* @notice Get the maximum flow rate allowed with the deposit
* @dev The deposit is clipped and rounded down
* @param deposit Deposit amount used for creating the flow
* @return flowRate The maximum flow rate
*/
function getMaximumFlowRateFromDeposit(
ISuperfluidToken token,
uint256 deposit)
external view virtual
returns (int96 flowRate);
/**
* @notice Get the deposit required for creating the flow
* @dev Calculates the deposit based on the liquidationPeriod and flowRate
* @param flowRate Flow rate to be tested
* @return deposit The deposit amount based on flowRate and liquidationPeriod
* @custom:note
* - if calculated deposit (flowRate * liquidationPeriod) is less
* than the minimum deposit, we use the minimum deposit otherwise
* we use the calculated deposit
*/
function getDepositRequiredForFlowRate(
ISuperfluidToken token,
int96 flowRate)
external view virtual
returns (uint256 deposit);
/**
* @dev Returns whether it is the patrician period based on host.getNow()
* @param account The account we are interested in
* @return isCurrentlyPatricianPeriod Whether it is currently the patrician period dictated by governance
* @return timestamp The value of host.getNow()
*/
function isPatricianPeriodNow(
ISuperfluidToken token,
address account)
public view virtual
returns (bool isCurrentlyPatricianPeriod, uint256 timestamp);
/**
* @dev Returns whether it is the patrician period based on timestamp
* @param account The account we are interested in
* @param timestamp The timestamp we are interested in observing the result of isPatricianPeriod
* @return bool Whether it is currently the patrician period dictated by governance
*/
function isPatricianPeriod(
ISuperfluidToken token,
address account,
uint256 timestamp
)
public view virtual
returns (bool);
/**
* @dev msgSender from `ctx` updates permissions for the `flowOperator` with `flowRateAllowance`
* @param token Super token address
* @param flowOperator The permission grantee address
* @param permissions A bitmask representation of the granted permissions
* @param flowRateAllowance The flow rate allowance the `flowOperator` is granted (only goes down)
* @param ctx Context bytes (see ISuperfluid.sol for Context struct)
*/
function updateFlowOperatorPermissions(
ISuperfluidToken token,
address flowOperator,
uint8 permissions,
int96 flowRateAllowance,
bytes calldata ctx
)
external virtual
returns(bytes memory newCtx);
/**
* @dev msgSender from `ctx` grants `flowOperator` all permissions with flowRateAllowance as type(int96).max
* @param token Super token address
* @param flowOperator The permission grantee address
* @param ctx Context bytes (see ISuperfluid.sol for Context struct)
*/
function authorizeFlowOperatorWithFullControl(
ISuperfluidToken token,
address flowOperator,
bytes calldata ctx
)
external virtual
returns(bytes memory newCtx);
/**
* @notice msgSender from `ctx` revokes `flowOperator` create/update/delete permissions
* @dev `permissions` and `flowRateAllowance` will both be set to 0
* @param token Super token address
* @param flowOperator The permission grantee address
* @param ctx Context bytes (see ISuperfluid.sol for Context struct)
*/
function revokeFlowOperatorWithFullControl(
ISuperfluidToken token,
address flowOperator,
bytes calldata ctx
)
external virtual
returns(bytes memory newCtx);
/**
* @notice Get the permissions of a flow operator between `sender` and `flowOperator` for `token`
* @param token Super token address
* @param sender The permission granter address
* @param flowOperator The permission grantee address
* @return flowOperatorId The keccak256 hash of encoded string "flowOperator", sender and flowOperator
* @return permissions A bitmask representation of the granted permissions
* @return flowRateAllowance The flow rate allowance the `flowOperator` is granted (only goes down)
*/
function getFlowOperatorData(
ISuperfluidToken token,
address sender,
address flowOperator
)
public view virtual
returns (
bytes32 flowOperatorId,
uint8 permissions,
int96 flowRateAllowance
);
/**
* @notice Get flow operator using flowOperatorId
* @param token Super token address
* @param flowOperatorId The keccak256 hash of encoded string "flowOperator", sender and flowOperator
* @return permissions A bitmask representation of the granted permissions
* @return flowRateAllowance The flow rate allowance the `flowOperator` is granted (only goes down)
*/
function getFlowOperatorDataByID(
ISuperfluidToken token,
bytes32 flowOperatorId
)
external view virtual
returns (
uint8 permissions,
int96 flowRateAllowance
);
/**
* @notice Create a flow betwen ctx.msgSender and receiver
* @dev flowId (agreementId) is the keccak256 hash of encoded sender and receiver
* @param token Super token address
* @param receiver Flow receiver address
* @param flowRate New flow rate in amount per second
* @param ctx Context bytes (see ISuperfluid.sol for Context struct)
*
* @custom:callbacks
* - AgreementCreated
* - agreementId - can be used in getFlowByID
* - agreementData - abi.encode(address flowSender, address flowReceiver)
*
* @custom:note
* - A deposit is taken as safety margin for the solvency agents
* - A extra gas fee may be taken to pay for solvency agent liquidations
*/
function createFlow(
ISuperfluidToken token,
address receiver,
int96 flowRate,
bytes calldata ctx
)
external virtual
returns(bytes memory newCtx);
/**
* @notice Create a flow between sender and receiver
* @dev A flow created by an approved flow operator (see above for details on callbacks)
* @param token Super token address
* @param sender Flow sender address (has granted permissions)
* @param receiver Flow receiver address
* @param flowRate New flow rate in amount per second
* @param ctx Context bytes (see ISuperfluid.sol for Context struct)
*/
function createFlowByOperator(
ISuperfluidToken token,
address sender,
address receiver,
int96 flowRate,
bytes calldata ctx
)
external virtual
returns(bytes memory newCtx);
/**
* @notice Update the flow rate between ctx.msgSender and receiver
* @dev flowId (agreementId) is the keccak256 hash of encoded sender and receiver
* @param token Super token address
* @param receiver Flow receiver address
* @param flowRate New flow rate in amount per second
* @param ctx Context bytes (see ISuperfluid.sol for Context struct)
*
* @custom:callbacks
* - AgreementUpdated
* - agreementId - can be used in getFlowByID
* - agreementData - abi.encode(address flowSender, address flowReceiver)
*
* @custom:note
* - Only the flow sender may update the flow rate
* - Even if the flow rate is zero, the flow is not deleted
* from the system
* - Deposit amount will be adjusted accordingly
* - No new gas fee is charged
*/
function updateFlow(
ISuperfluidToken token,
address receiver,
int96 flowRate,
bytes calldata ctx
)
external virtual
returns(bytes memory newCtx);
/**
* @notice Update a flow between sender and receiver
* @dev A flow updated by an approved flow operator (see above for details on callbacks)
* @param token Super token address
* @param sender Flow sender address (has granted permissions)
* @param receiver Flow receiver address
* @param flowRate New flow rate in amount per second
* @param ctx Context bytes (see ISuperfluid.sol for Context struct)
*/
function updateFlowByOperator(
ISuperfluidToken token,
address sender,
address receiver,
int96 flowRate,
bytes calldata ctx
)
external virtual
returns(bytes memory newCtx);
/**
* @dev Get the flow data between `sender` and `receiver` of `token`
* @param token Super token address
* @param sender Flow receiver
* @param receiver Flow sender
* @return timestamp Timestamp of when the flow is updated
* @return flowRate The flow rate
* @return deposit The amount of deposit the flow
* @return owedDeposit The amount of owed deposit of the flow
*/
function getFlow(
ISuperfluidToken token,
address sender,
address receiver
)
external view virtual
returns (
uint256 timestamp,
int96 flowRate,
uint256 deposit,
uint256 owedDeposit
);
/**
* @notice Get flow data using agreementId
* @dev flowId (agreementId) is the keccak256 hash of encoded sender and receiver
* @param token Super token address
* @param agreementId The agreement ID
* @return timestamp Timestamp of when the flow is updated
* @return flowRate The flow rate
* @return deposit The deposit amount of the flow
* @return owedDeposit The owed deposit amount of the flow
*/
function getFlowByID(
ISuperfluidToken token,
bytes32 agreementId
)
external view virtual
returns (
uint256 timestamp,
int96 flowRate,
uint256 deposit,
uint256 owedDeposit
);
/**
* @dev Get the aggregated flow info of the account
* @param token Super token address
* @param account Account for the query
* @return timestamp Timestamp of when a flow was last updated for account
* @return flowRate The net flow rate of token for account
* @return deposit The sum of all deposits for account's flows
* @return owedDeposit The sum of all owed deposits for account's flows
*/
function getAccountFlowInfo(
ISuperfluidToken token,
address account
)
external view virtual
returns (
uint256 timestamp,
int96 flowRate,
uint256 deposit,
uint256 owedDeposit);
/**
* @dev Get the net flow rate of the account
* @param token Super token address
* @param account Account for the query
* @return flowRate Net flow rate
*/
function getNetFlow(
ISuperfluidToken token,
address account
)
external view virtual
returns (int96 flowRate);
/**
* @notice Delete the flow between sender and receiver
* @dev flowId (agreementId) is the keccak256 hash of encoded sender and receiver
* @param token Super token address
* @param ctx Context bytes (see ISuperfluid.sol for Context struct)
* @param receiver Flow receiver address
*
* @custom:callbacks
* - AgreementTerminated
* - agreementId - can be used in getFlowByID
* - agreementData - abi.encode(address flowSender, address flowReceiver)
*
* @custom:note
* - Both flow sender and receiver may delete the flow
* - If Sender account is insolvent or in critical state, a solvency agent may
* also terminate the agreement
* - Gas fee may be returned to the sender
*/
function deleteFlow(
ISuperfluidToken token,
address sender,
address receiver,
bytes calldata ctx
)
external virtual
returns(bytes memory newCtx);
/**
* @notice Delete the flow between sender and receiver
* @dev A flow deleted by an approved flow operator (see above for details on callbacks)
* @param token Super token address
* @param ctx Context bytes (see ISuperfluid.sol for Context struct)
* @param receiver Flow receiver address
*/
function deleteFlowByOperator(
ISuperfluidToken token,
address sender,
address receiver,
bytes calldata ctx
)
external virtual
returns(bytes memory newCtx);
/**
* @dev Flow operator updated event
* @param token Super token address
* @param sender Flow sender address
* @param flowOperator Flow operator address
* @param permissions Octo bitmask representation of permissions
* @param flowRateAllowance The flow rate allowance the `flowOperator` is granted (only goes down)
*/
event FlowOperatorUpdated(
ISuperfluidToken indexed token,
address indexed sender,
address indexed flowOperator,
uint8 permissions,
int96 flowRateAllowance
);
/**
* @dev Flow updated event
* @param token Super token address
* @param sender Flow sender address
* @param receiver Flow recipient address
* @param flowRate Flow rate in amount per second for this flow
* @param totalSenderFlowRate Total flow rate in amount per second for the sender
* @param totalReceiverFlowRate Total flow rate in amount per second for the receiver
* @param userData The user provided data
*
*/
event FlowUpdated(
ISuperfluidToken indexed token,
address indexed sender,
address indexed receiver,
int96 flowRate,
int256 totalSenderFlowRate,
int256 totalReceiverFlowRate,
bytes userData
);
/**
* @dev Flow updated extension event
* @param flowOperator Flow operator address - the Context.msgSender
* @param deposit The deposit amount for the stream
*/
event FlowUpdatedExtension(
address indexed flowOperator,
uint256 deposit
);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { IERC173Internal } from './IERC173Internal.sol';
/**
* @title Contract ownership standard interface
* @dev see https://eips.ethereum.org/EIPS/eip-173
*/
interface IERC173 is IERC173Internal {
/**
* @notice get the ERC173 contract owner
* @return conrtact owner
*/
function owner() external view returns (address);
/**
* @notice transfer contract ownership to new account
* @param account address of new owner
*/
function transferOwnership(address account) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { UintUtils } from './UintUtils.sol';
library AddressUtils {
using UintUtils for uint256;
function toString(address account) internal pure returns (string memory) {
return uint256(uint160(account)).toHexString(20);
}
function isContract(address account) internal view returns (bool) {
uint256 size;
assembly {
size := extcodesize(account)
}
return size > 0;
}
function sendValue(address payable account, uint256 amount) internal {
(bool success, ) = account.call{ value: amount }('');
require(success, 'AddressUtils: failed to send value');
}
function functionCall(address target, bytes memory data)
internal
returns (bytes memory)
{
return
functionCall(target, data, 'AddressUtils: failed low-level call');
}
function functionCall(
address target,
bytes memory data,
string memory error
) internal returns (bytes memory) {
return _functionCallWithValue(target, data, 0, error);
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return
functionCallWithValue(
target,
data,
value,
'AddressUtils: failed low-level call with value'
);
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory error
) internal returns (bytes memory) {
require(
address(this).balance >= value,
'AddressUtils: insufficient balance for call'
);
return _functionCallWithValue(target, data, value, error);
}
function _functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory error
) private returns (bytes memory) {
require(
isContract(target),
'AddressUtils: function call to non-contract'
);
(bool success, bytes memory returnData) = target.call{ value: value }(
data
);
if (success) {
return returnData;
} else if (returnData.length > 0) {
assembly {
let returnData_size := mload(returnData)
revert(add(32, returnData), returnData_size)
}
} else {
revert(error);
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import { IERC173Internal } from '../../interfaces/IERC173Internal.sol';
interface IOwnableInternal is IERC173Internal {}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
/**
* @title Partial ERC173 interface needed by internal functions
*/
interface IERC173Internal {
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
/**
* @title utility functions for uint256 operations
* @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts/ (MIT license)
*/
library UintUtils {
bytes16 private constant HEX_SYMBOLS = '0123456789abcdef';
function toString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return '0';
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
function toHexString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return '0x00';
}
uint256 length = 0;
for (uint256 temp = value; temp != 0; temp >>= 8) {
unchecked {
length++;
}
}
return toHexString(value, length);
}
function toHexString(uint256 value, uint256 length)
internal
pure
returns (string memory)
{
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = '0';
buffer[1] = 'x';
unchecked {
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = HEX_SYMBOLS[value & 0xf];
value >>= 4;
}
}
require(value == 0, 'UintUtils: hex length insufficient');
return string(buffer);
}
}{
"optimizer": {
"enabled": false,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"metadata": {
"useLiteralContent": true
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"name":"getBeneficiary","outputs":[{"internalType":"contract ICFABeneficiary","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBidPeriodLengthInSeconds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getHost","outputs":[{"internalType":"contract ISuperfluid","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMinForSalePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPaymentToken","outputs":[{"internalType":"contract ISuperToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPenaltyDenominator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPenaltyNumerator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPerSecondFeeDenominator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPerSecondFeeNumerator","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getReclaimAuctionLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ICFABeneficiary","name":"beneficiary","type":"address"},{"internalType":"contract ISuperToken","name":"paymentToken","type":"address"},{"internalType":"contract ISuperfluid","name":"host","type":"address"},{"internalType":"uint256","name":"perSecondFeeNumerator","type":"uint256"},{"internalType":"uint256","name":"perSecondFeeDenominator","type":"uint256"},{"internalType":"uint256","name":"penaltyNumerator","type":"uint256"},{"internalType":"uint256","name":"penaltyDenominator","type":"uint256"},{"internalType":"uint256","name":"bidPeriodLengthInSeconds","type":"uint256"},{"internalType":"uint256","name":"reclaimAuctionLength","type":"uint256"},{"internalType":"uint256","name":"minForSalePrice","type":"uint256"}],"name":"initializeParams","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ICFABeneficiary","name":"beneficiary","type":"address"}],"name":"setBeneficiary","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"bidPeriodLengthInSeconds","type":"uint256"}],"name":"setBidPeriodLengthInSeconds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISuperfluid","name":"host","type":"address"}],"name":"setHost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"minForSalePrice","type":"uint256"}],"name":"setMinForSalePrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISuperToken","name":"paymentToken","type":"address"}],"name":"setPaymentToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"penaltyDenominator","type":"uint256"}],"name":"setPenaltyDenominator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"penaltyNumerator","type":"uint256"}],"name":"setPenaltyNumerator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"perSecondFeeDenominator","type":"uint256"}],"name":"setPerSecondFeeDenominator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"perSecondFeeNumerator","type":"uint256"}],"name":"setPerSecondFeeNumerator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"reclaimAuctionLength","type":"uint256"}],"name":"setReclaimAuctionLength","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
608060405234801561001057600080fd5b5061132b806100206000396000f3fe608060405234801561001057600080fd5b50600436106101375760003560e01c806377742126116100b8578063a3cecf831161007c578063a3cecf83146102f0578063bf7cdf6d1461030c578063c13ed2ec14610328578063c85e0be214610346578063d41c3a6514610362578063de7aff3c1461038057610137565b806377742126146102605780637c627e1b1461027c5780637d28dfc9146102985780637d51ce90146102b4578063801c5b1e146102d257610137565b80634d73f0b4116100ff5780634d73f0b4146101d0578063520aa8ee146101ec578063565a2e2c1461020a5780636a326ab11461022857806373a299311461024457610137565b8063014df4141461013c57806316a310261461015a5780631c31f7101461017857806320bc442514610194578063356248da146101b2575b600080fd5b61014461039c565b6040516101519190610ebb565b60405180910390f35b6101626103b4565b60405161016f9190610ebb565b60405180910390f35b610192600480360381019061018d9190610f4b565b6103cc565b005b61019c6104b8565b6040516101a99190610fd7565b60405180910390f35b6101ba6104f0565b6040516101c79190610ebb565b60405180910390f35b6101ea60048036038101906101e5919061101e565b610508565b005b6101f46105ba565b6040516102019190610ebb565b60405180910390f35b6102126105d2565b60405161021f919061106c565b60405180910390f35b610242600480360381019061023d91906110c5565b61060a565b005b61025e6004803603810190610259919061101e565b6106f6565b005b61027a6004803603810190610275919061101e565b6107a8565b005b6102966004803603810190610291919061101e565b61085a565b005b6102b260048036038101906102ad9190611130565b61090c565b005b6102bc610ac6565b6040516102c99190610ebb565b60405180910390f35b6102da610ade565b6040516102e79190610ebb565b60405180910390f35b61030a6004803603810190610305919061101e565b610af6565b005b6103266004803603810190610321919061101e565b610ba8565b005b610330610c5a565b60405161033d9190610ebb565b60405180910390f35b610360600480360381019061035b919061120f565b610c72565b005b61036a610d5e565b604051610377919061125d565b60405180910390f35b61039a6004803603810190610395919061101e565b610d96565b005b6000806103a7610e48565b9050806004015491505090565b6000806103bf610e48565b9050806003015491505090565b6103d4610e75565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610465576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161045c906112d5565b60405180910390fd5b600061046f610e48565b9050818160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6000806104c3610e48565b90508060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691505090565b6000806104fb610e48565b9050806009015491505090565b610510610e75565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105a1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610598906112d5565b60405180910390fd5b60006105ab610e48565b90508181600401819055505050565b6000806105c5610e48565b9050806008015491505090565b6000806105dd610e48565b90508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691505090565b610612610e75565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146106a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161069a906112d5565b60405180910390fd5b60006106ad610e48565b9050818160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6106fe610e75565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461078f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610786906112d5565b60405180910390fd5b6000610799610e48565b90508181600501819055505050565b6107b0610e75565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610841576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610838906112d5565b60405180910390fd5b600061084b610e48565b90508181600801819055505050565b610862610e75565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146108f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ea906112d5565b60405180910390fd5b60006108fd610e48565b90508181600601819055505050565b610914610e75565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146109a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161099c906112d5565b60405180910390fd5b60006109af610e48565b90508a8160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550898160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550888160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508781600301819055508681600401819055508581600501819055508481600601819055508381600701819055508281600801819055508181600901819055505050505050505050505050565b600080610ad1610e48565b9050806006015491505090565b600080610ae9610e48565b9050806007015491505090565b610afe610e75565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610b8f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b86906112d5565b60405180910390fd5b6000610b99610e48565b90508181600301819055505050565b610bb0610e75565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610c41576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c38906112d5565b60405180910390fd5b6000610c4b610e48565b90508181600701819055505050565b600080610c65610e48565b9050806005015491505090565b610c7a610e75565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d0b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d02906112d5565b60405180910390fd5b6000610d15610e48565b9050818160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b600080610d69610e48565b90508060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691505090565b610d9e610e75565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e2f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e26906112d5565b60405180910390fd5b6000610e39610e48565b90508181600901819055505050565b6000807f6ee8bf8f33d87ee8fc792bdab0fa8c5d1fb2132b416aab215664bf4732bc299790508091505090565b6000807f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f67168046090508091505090565b6000819050919050565b610eb581610ea2565b82525050565b6000602082019050610ed06000830184610eac565b92915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610f0682610edb565b9050919050565b6000610f1882610efb565b9050919050565b610f2881610f0d565b8114610f3357600080fd5b50565b600081359050610f4581610f1f565b92915050565b600060208284031215610f6157610f60610ed6565b5b6000610f6f84828501610f36565b91505092915050565b6000819050919050565b6000610f9d610f98610f9384610edb565b610f78565b610edb565b9050919050565b6000610faf82610f82565b9050919050565b6000610fc182610fa4565b9050919050565b610fd181610fb6565b82525050565b6000602082019050610fec6000830184610fc8565b92915050565b610ffb81610ea2565b811461100657600080fd5b50565b60008135905061101881610ff2565b92915050565b60006020828403121561103457611033610ed6565b5b600061104284828501611009565b91505092915050565b600061105682610fa4565b9050919050565b6110668161104b565b82525050565b6000602082019050611081600083018461105d565b92915050565b600061109282610efb565b9050919050565b6110a281611087565b81146110ad57600080fd5b50565b6000813590506110bf81611099565b92915050565b6000602082840312156110db576110da610ed6565b5b60006110e9848285016110b0565b91505092915050565b60006110fd82610efb565b9050919050565b61110d816110f2565b811461111857600080fd5b50565b60008135905061112a81611104565b92915050565b6000806000806000806000806000806101408b8d03121561115457611153610ed6565b5b60006111628d828e01610f36565b9a505060206111738d828e016110b0565b99505060406111848d828e0161111b565b98505060606111958d828e01611009565b97505060806111a68d828e01611009565b96505060a06111b78d828e01611009565b95505060c06111c88d828e01611009565b94505060e06111d98d828e01611009565b9350506101006111eb8d828e01611009565b9250506101206111fd8d828e01611009565b9150509295989b9194979a5092959850565b60006020828403121561122557611224610ed6565b5b60006112338482850161111b565b91505092915050565b600061124782610fa4565b9050919050565b6112578161123c565b82525050565b6000602082019050611272600083018461124e565b92915050565b600082825260208201905092915050565b7f4f776e61626c653a2073656e646572206d757374206265206f776e6572000000600082015250565b60006112bf601d83611278565b91506112ca82611289565b602082019050919050565b600060208201905081810360008301526112ee816112b2565b905091905056fea26469706673582212203532d986a5376a6d6abcb228443e8743023c22f57f3fae7587eb55d611a4e5fa64736f6c63430008100033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101375760003560e01c806377742126116100b8578063a3cecf831161007c578063a3cecf83146102f0578063bf7cdf6d1461030c578063c13ed2ec14610328578063c85e0be214610346578063d41c3a6514610362578063de7aff3c1461038057610137565b806377742126146102605780637c627e1b1461027c5780637d28dfc9146102985780637d51ce90146102b4578063801c5b1e146102d257610137565b80634d73f0b4116100ff5780634d73f0b4146101d0578063520aa8ee146101ec578063565a2e2c1461020a5780636a326ab11461022857806373a299311461024457610137565b8063014df4141461013c57806316a310261461015a5780631c31f7101461017857806320bc442514610194578063356248da146101b2575b600080fd5b61014461039c565b6040516101519190610ebb565b60405180910390f35b6101626103b4565b60405161016f9190610ebb565b60405180910390f35b610192600480360381019061018d9190610f4b565b6103cc565b005b61019c6104b8565b6040516101a99190610fd7565b60405180910390f35b6101ba6104f0565b6040516101c79190610ebb565b60405180910390f35b6101ea60048036038101906101e5919061101e565b610508565b005b6101f46105ba565b6040516102019190610ebb565b60405180910390f35b6102126105d2565b60405161021f919061106c565b60405180910390f35b610242600480360381019061023d91906110c5565b61060a565b005b61025e6004803603810190610259919061101e565b6106f6565b005b61027a6004803603810190610275919061101e565b6107a8565b005b6102966004803603810190610291919061101e565b61085a565b005b6102b260048036038101906102ad9190611130565b61090c565b005b6102bc610ac6565b6040516102c99190610ebb565b60405180910390f35b6102da610ade565b6040516102e79190610ebb565b60405180910390f35b61030a6004803603810190610305919061101e565b610af6565b005b6103266004803603810190610321919061101e565b610ba8565b005b610330610c5a565b60405161033d9190610ebb565b60405180910390f35b610360600480360381019061035b919061120f565b610c72565b005b61036a610d5e565b604051610377919061125d565b60405180910390f35b61039a6004803603810190610395919061101e565b610d96565b005b6000806103a7610e48565b9050806004015491505090565b6000806103bf610e48565b9050806003015491505090565b6103d4610e75565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610465576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161045c906112d5565b60405180910390fd5b600061046f610e48565b9050818160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6000806104c3610e48565b90508060020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691505090565b6000806104fb610e48565b9050806009015491505090565b610510610e75565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146105a1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610598906112d5565b60405180910390fd5b60006105ab610e48565b90508181600401819055505050565b6000806105c5610e48565b9050806008015491505090565b6000806105dd610e48565b90508060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691505090565b610612610e75565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146106a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161069a906112d5565b60405180910390fd5b60006106ad610e48565b9050818160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6106fe610e75565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461078f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610786906112d5565b60405180910390fd5b6000610799610e48565b90508181600501819055505050565b6107b0610e75565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610841576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610838906112d5565b60405180910390fd5b600061084b610e48565b90508181600801819055505050565b610862610e75565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146108f3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ea906112d5565b60405180910390fd5b60006108fd610e48565b90508181600601819055505050565b610914610e75565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146109a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161099c906112d5565b60405180910390fd5b60006109af610e48565b90508a8160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550898160010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550888160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508781600301819055508681600401819055508581600501819055508481600601819055508381600701819055508281600801819055508181600901819055505050505050505050505050565b600080610ad1610e48565b9050806006015491505090565b600080610ae9610e48565b9050806007015491505090565b610afe610e75565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610b8f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b86906112d5565b60405180910390fd5b6000610b99610e48565b90508181600301819055505050565b610bb0610e75565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610c41576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c38906112d5565b60405180910390fd5b6000610c4b610e48565b90508181600701819055505050565b600080610c65610e48565b9050806005015491505090565b610c7a610e75565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610d0b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d02906112d5565b60405180910390fd5b6000610d15610e48565b9050818160020160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b600080610d69610e48565b90508060010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1691505090565b610d9e610e75565b60000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e2f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e26906112d5565b60405180910390fd5b6000610e39610e48565b90508181600901819055505050565b6000807f6ee8bf8f33d87ee8fc792bdab0fa8c5d1fb2132b416aab215664bf4732bc299790508091505090565b6000807f8a22373512790c48b83a1fe2efdd2888d4a917bcdc24d0adf63e60f67168046090508091505090565b6000819050919050565b610eb581610ea2565b82525050565b6000602082019050610ed06000830184610eac565b92915050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000610f0682610edb565b9050919050565b6000610f1882610efb565b9050919050565b610f2881610f0d565b8114610f3357600080fd5b50565b600081359050610f4581610f1f565b92915050565b600060208284031215610f6157610f60610ed6565b5b6000610f6f84828501610f36565b91505092915050565b6000819050919050565b6000610f9d610f98610f9384610edb565b610f78565b610edb565b9050919050565b6000610faf82610f82565b9050919050565b6000610fc182610fa4565b9050919050565b610fd181610fb6565b82525050565b6000602082019050610fec6000830184610fc8565b92915050565b610ffb81610ea2565b811461100657600080fd5b50565b60008135905061101881610ff2565b92915050565b60006020828403121561103457611033610ed6565b5b600061104284828501611009565b91505092915050565b600061105682610fa4565b9050919050565b6110668161104b565b82525050565b6000602082019050611081600083018461105d565b92915050565b600061109282610efb565b9050919050565b6110a281611087565b81146110ad57600080fd5b50565b6000813590506110bf81611099565b92915050565b6000602082840312156110db576110da610ed6565b5b60006110e9848285016110b0565b91505092915050565b60006110fd82610efb565b9050919050565b61110d816110f2565b811461111857600080fd5b50565b60008135905061112a81611104565b92915050565b6000806000806000806000806000806101408b8d03121561115457611153610ed6565b5b60006111628d828e01610f36565b9a505060206111738d828e016110b0565b99505060406111848d828e0161111b565b98505060606111958d828e01611009565b97505060806111a68d828e01611009565b96505060a06111b78d828e01611009565b95505060c06111c88d828e01611009565b94505060e06111d98d828e01611009565b9350506101006111eb8d828e01611009565b9250506101206111fd8d828e01611009565b9150509295989b9194979a5092959850565b60006020828403121561122557611224610ed6565b5b60006112338482850161111b565b91505092915050565b600061124782610fa4565b9050919050565b6112578161123c565b82525050565b6000602082019050611272600083018461124e565b92915050565b600082825260208201905092915050565b7f4f776e61626c653a2073656e646572206d757374206265206f776e6572000000600082015250565b60006112bf601d83611278565b91506112ca82611289565b602082019050919050565b600060208201905081810360008301526112ee816112b2565b905091905056fea26469706673582212203532d986a5376a6d6abcb228443e8743023c22f57f3fae7587eb55d611a4e5fa64736f6c63430008100033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.