Contract Address Details
contract
0xb7DE52F4281a7a276E18C40F94cd93159C4A2d22
- Contract Name
- TOGA
- Creator
- 0x3c8a79–b1fd21 at 0xdc72bb–8888ad
- Balance
- 0 xDAI ( )
- Tokens
-
Fetching tokens...
- Transactions
- 1 Transactions
- Transfers
- 14 Transfers
- Gas Used
- 330,124
- Last Balance Update
- 22945308
Transactions
Token Transfers
Tokens
Internal Transactions
Coin Balance History
Logs
Code
Read Contract
Write Contract
This contract has been verified via Sourcify.
View contract in Sourcify repository
- Contract name:
- TOGA
- Optimization enabled
- true
- Compiler version
- v0.7.6+commit.7338295f
- Optimization runs
- 200
- EVM Version
- istanbul
- Verified at
- 2021-12-22T18:36:58.745196Z
project:/contracts/utils/TOGA.sol
// SPDX-License-Identifier: AGPLv3 pragma solidity 0.7.6; import { ISuperfluid, ISuperToken, ISuperfluidToken } from "../interfaces/superfluid/ISuperfluid.sol"; import { IConstantFlowAgreementV1 } from "../interfaces/agreements/IConstantFlowAgreementV1.sol"; import { IERC1820Registry } from "@openzeppelin/contracts/introspection/IERC1820Registry.sol"; import { IERC777Recipient } from "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol"; import { TokenCustodian } from "./TokenCustodian.sol"; /** * @title TOGA: Transparent Ongoing Auction * * TOGA is a simple implementation of a continuous auction. * It's used to designate PICs (Patrician In Charge) - a role defined per Super Token. * Anybody can become the PIC for a Super Token by staking the highest bond (denominated in the token). * Staking is done by simply using ERC777.send(), transferring the bond amount to be staked to this contract. * Via userData parameter (abi-encoded int96), an exitRate can be defined. If omitted, a default will be chosen. * The exitRate is the flowrate at which the bond is streamed back to the PIC. * Any rewards accrued by this contract (in general the whole token balance) become part of the bond. * When a PIC is outbid, the current bond is transferred to it with ERC777.send(). * * changes in v2: * In case that send() fails (e.g. due to a reverting hook), the bond is transferred to a custodian contract. * Funds accumulated there can be withdrawn from there at any time. * The current PIC can increase its bond by sending more funds using ERC777.send(). * * @author Superfluid */ interface ITOGAv1 { /** * @dev get the address of the current PIC for the given token. * @param token The token for which to get the PIC */ function getCurrentPIC(ISuperToken token) external view returns(address pic); /** * @dev get info about the state - most importantly the bond amount - of the current PIC for the given token. * @param token The token for which to get PIC info * Notes: * The bond changes dynamically and can both grow or shrink between 2 blocks. * Even the PIC itself could change anytime, this being a continuous auction. * @return pic Address of the current PIC. Returns the ZERO address if not set * @return bond The current bond amount. Can shrink or grow over time, depending on exitRate and rewards accrued * @return exitRate The current flowrate of given tokens from the contract to the PIC */ function getCurrentPICInfo(ISuperToken token) external view returns(address pic, uint256 bond, int96 exitRate); /** * @dev Get the exit rate set by default for the given token and bond amount * @param token The token for which to get info * @param bondAmount The bond amount for which to make the calculation * @return exitRate The exit rate set by default for a bid with the given bond amount for the given token */ function getDefaultExitRateFor(ISuperToken token, uint256 bondAmount) external view returns(int96 exitRate); /** * @dev Get the max exit which can be set for the given token and bond amount * @param token The token for which to get info * @param bondAmount The bond amount for which to calculate the max exit rate * @return exitRate The max exit rate which can be set for the given bond amount and token * * This limit is enforced only at the time of setting or updating the flow from the contract to the PIC. */ function getMaxExitRateFor(ISuperToken token, uint256 bondAmount) external view returns(int96 exitRate); /** * @dev allows the current PIC for the given token to change the exit rate * @param token The Super Token the exit rate should be changed for * @param newExitRate The new exit rate. The same constraints as during bidding apply. * * Notes: * newExitRate can't be higher than the value returned by getMaxExitRateFor() for the given token and bond. * newExitRate can also be 0, this triggers closing of the flow from the contract to the PIC. * If newExitRate is > 0 and no flow exists, a flow is created. */ function changeExitRate(ISuperToken token, int96 newExitRate) external; /** * @dev Emitted on a successful bid designating a PIC * @param token The Super token the new PIC bid for * @param pic The address of the new PIC * @param bond The size (amount) of the bond staked by the PIC * @param exitRate The flowrate at which the bond and accrued rewards will be streamed to the PIC * The exitRate must be greater or equal zero and respect the upper bound defined by getMaxExitRateFor() */ event NewPIC(ISuperToken indexed token, address pic, uint256 bond, int96 exitRate); /** * @dev Emitted if a PIC changes the exit rate * @param token The Super token for which the exit rate was changed * @param exitRate The new flowrate of the given token from the contract to the PIC */ event ExitRateChanged(ISuperToken indexed token, int96 exitRate); } interface ITOGAv2 is ITOGAv1 { /** * @dev allows previous PICs to withdraw bonds which couldn't be sent back to them * @param token The token for which to withdraw funds in custody */ function withdrawFundsInCustody(ISuperToken token) external; /** * @dev Emitted if a PIC increases its bond * @param additionalBond The additional amount added to the bond */ event BondIncreased(ISuperToken indexed token, uint256 additionalBond); } contract TOGA is ITOGAv2, IERC777Recipient { // lightweight struct packing an address and a bool (reentrancy guard) into 1 word struct LockablePIC { address addr; bool lock; } mapping(ISuperToken => LockablePIC) internal _currentPICs; ISuperfluid internal immutable _host; IConstantFlowAgreementV1 internal immutable _cfa; uint256 public immutable minBondDuration; IERC1820Registry constant internal _ERC1820_REG = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24); // solhint-disable-next-line var-name-mixedcase uint64 immutable public ERC777_SEND_GAS_LIMIT = 3000000; // takes custody of bonds which the TOGA fails to send back to an outbid PIC TokenCustodian public custodian; constructor(ISuperfluid host_, uint256 minBondDuration_, TokenCustodian custodian_) { _host = ISuperfluid(host_); minBondDuration = minBondDuration_; _cfa = IConstantFlowAgreementV1( address(host_.getAgreementClass(keccak256("org.superfluid-finance.agreements.ConstantFlowAgreement.v1"))) ); bytes32 erc777TokensRecipientHash = keccak256("ERC777TokensRecipient"); _ERC1820_REG.setInterfaceImplementer(address(this), erc777TokensRecipientHash, address(this)); _ERC1820_REG.setInterfaceImplementer(address(this), keccak256("TOGAv1"), address(this)); _ERC1820_REG.setInterfaceImplementer(address(this), keccak256("TOGAv2"), address(this)); require( _ERC1820_REG.getInterfaceImplementer(address(custodian_), erc777TokensRecipientHash) == address(custodian_), "TOGA: invalid custodian" ); custodian = custodian_; } function getCurrentPIC(ISuperToken token) external view override returns(address pic) { return _currentPICs[token].addr; } function getCurrentPICInfo(ISuperToken token) external view override returns(address pic, uint256 bond, int96 exitRate) { (, exitRate,,) = _cfa.getFlow(token, address(this), _currentPICs[token].addr); return ( _currentPICs[token].addr, _getCurrentPICBond(token), exitRate ); } function getDefaultExitRateFor(ISuperToken /*token*/, uint256 bondAmount) public view override returns(int96 exitRate) { return int96(bondAmount / (minBondDuration * 4)); } function getMaxExitRateFor(ISuperToken /*token*/, uint256 bondAmount) external view override returns(int96 exitRate) { return int96(bondAmount / minBondDuration); } function changeExitRate(ISuperToken token, int96 newExitRate) external override { address currentPICAddr = _currentPICs[token].addr; require(msg.sender == currentPICAddr, "TOGA: only PIC allowed"); require(newExitRate >= 0, "TOGA: negative exitRate not allowed"); require(uint256(newExitRate) * minBondDuration <= _getCurrentPICBond(token), "TOGA: exitRate too high"); (, int96 curExitRate,,) = _cfa.getFlow(token, address(this), currentPICAddr); if (curExitRate > 0 && newExitRate > 0) { // need to update existing flow _host.callAgreement( _cfa, abi.encodeWithSelector( _cfa.updateFlow.selector, token, currentPICAddr, newExitRate, new bytes(0) ), "0x" ); } else if (curExitRate == 0 && newExitRate > 0) { // no pre-existing flow, need to create _host.callAgreement( _cfa, abi.encodeWithSelector( _cfa.createFlow.selector, token, currentPICAddr, newExitRate, new bytes(0) ), "0x" ); } else if (curExitRate > 0 && newExitRate == 0) { // need to close existing flow _host.callAgreement( _cfa, abi.encodeWithSelector( _cfa.deleteFlow.selector, token, address(this), currentPICAddr, new bytes(0) ), "0x" ); } // else do nothing (no existing flow, newExitRate == 0) emit ExitRateChanged(token, newExitRate); } function withdrawFundsInCustody(ISuperToken token) external override { custodian.flush(token, msg.sender); } // ============ internal ============ function _getCurrentPICBond(ISuperToken token) internal view returns(uint256 bond) { (int256 availBal, uint256 deposit, , ) = token.realtimeBalanceOfNow(address(this)); // The protocol guarantees that we get no values leading to an overflow here return availBal + int256(deposit) > 0 ? uint256(availBal + int256(deposit)) : 0; } // This is the logic for designating a PIC via successful bid - invoked only by the ERC777 send() hook // Relies on CFA (SuperApp) hooks not being able to block the transaction by reverting. function _becomePIC(ISuperToken token, address newPIC, uint256 amount, int96 exitRate) internal { require(!_currentPICs[token].lock, "TOGA: reentrancy not allowed"); require(exitRate >= 0, "TOGA: negative exitRate not allowed"); require(uint256(exitRate) * minBondDuration <= amount, "TOGA: exitRate too high"); // cannot underflow because amount was added to the balance before uint256 currentPICBond = _getCurrentPICBond(token) - amount; require(amount > currentPICBond, "TOGA: bid too low"); address currentPICAddr = _currentPICs[token].addr; _currentPICs[token].lock = true; // set reentrancy guard // close flow to current (soon previous) PIC if exists (, int96 curFlowRate,,) = _cfa.getFlow(token, address(this), currentPICAddr); if (curFlowRate > 0) { _host.callAgreement( _cfa, abi.encodeWithSelector( _cfa.deleteFlow.selector, token, address(this), currentPICAddr, new bytes(0) ), "0x" ); } // if no PIC was set yet, rewards already accumulated become part of the bond of the first PIC if (currentPICAddr != address(0)) { // send remaining bond to current PIC // solhint-disable-next-line check-send-result try token.send{gas: ERC777_SEND_GAS_LIMIT}(currentPICAddr, currentPICBond, "0x") // solhint-disable-next-line no-empty-blocks {} catch { // if sending failed, move the remaining bond to a custody contract // the current PIC can withdraw it in a separate tx anytime later // solhint-disable-next-line check-send-result, multiple-sends token.send(address(custodian), currentPICBond, abi.encode(currentPICAddr)); } } // set new PIC // solhint-disable-next-line reentrancy _currentPICs[token].addr = newPIC; // if exitRate > 0, open stream to new PIC if (exitRate > 0) { _host.callAgreement( _cfa, abi.encodeWithSelector( _cfa.createFlow.selector, token, newPIC, exitRate, new bytes(0) ), "0x" ); } // solhint-disable-next-line reentrancy _currentPICs[token].lock = false; // release reentrancy guard emit NewPIC(token, newPIC, amount, exitRate); } // ============ IERC777Recipient ============ function tokensReceived( address /*operator*/, address from, address /*to*/, uint256 amount, bytes calldata userData, bytes calldata /*operatorData*/ ) override external { // if it's not a SuperToken, something will revert along the way ISuperToken token = ISuperToken(msg.sender); if(from != _currentPICs[token].addr) { int96 exitRate = userData.length == 0 ? getDefaultExitRateFor(token, amount) : abi.decode(userData, (int96)); _becomePIC(token, from, amount, exitRate); } else { // current PIC increases the bond emit BondIncreased(token, amount); } } }
/project_/contracts/utils/TokenCustodian.sol
// SPDX-License-Identifier: AGPLv3 pragma solidity 0.7.6; import { IERC777 } from "@openzeppelin/contracts/token/ERC777/IERC777.sol"; import { IERC1820Registry } from "@openzeppelin/contracts/introspection/IERC1820Registry.sol"; import { IERC777Recipient } from "@openzeppelin/contracts/token/ERC777/IERC777Recipient.sol"; // contract which takes custody of funds which couldn't be sent to the designated recipient contract TokenCustodian is IERC777Recipient { IERC1820Registry constant internal _ERC1820_REGISTRY = IERC1820Registry(0x1820a4B7618BdE71Dce8cdc73aAB6C95905faD24); mapping(IERC777 => mapping(address => uint256)) public balances; constructor() { _ERC1820_REGISTRY.setInterfaceImplementer(address(this), keccak256("ERC777TokensRecipient"), address(this)); } event CustodianDeposit(IERC777 indexed token, address recipient, uint256 amount); event CustodianWithdrawal(IERC777 indexed token, address recipient, uint256 amount); // transfers tokens it has in custody for the given recipient to it function flush(IERC777 token, address recipient) public { uint256 amount = balances[token][recipient]; if (amount > 0) { balances[token][recipient] = 0; // solhint-disable-next-line check-send-result token.send(recipient, amount, "0x0"); emit CustodianWithdrawal(token, recipient, amount); } } // ============ IERC777Recipient ============ // interface through which ERC777 tokens are deposited to this contract. // requires userData to contain an abi-encoded address which designates the recipient for which the deposit is made. function tokensReceived( address /*operator*/, address /*from*/, address /*to*/, uint256 amount, bytes calldata userData, bytes calldata /*operatorData*/ ) override external { IERC777 token = IERC777(msg.sender); // note: if userData is not set or not decodable as address, this will revert address recipient = abi.decode(userData, (address)); balances[token][recipient] += amount; emit CustodianDeposit(token, recipient, amount); // note: anybody could call this function and store balance entries. We can just ignore that, does no harm. } }
/project_/contracts/interfaces/tokens/TokenInfo.sol
// SPDX-License-Identifier: AGPLv3 pragma solidity >= 0.5.0; /** * @dev ERC20 token info interface * * NOTE: 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); }
/project_/contracts/interfaces/tokens/ERC20WithTokenInfo.sol
// SPDX-License-Identifier: AGPLv3 pragma solidity >= 0.5.0; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { TokenInfo } from "./TokenInfo.sol"; /** * * @dev Interface for ERC20 token with token info * * NOTE: 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 {}
/project_/contracts/interfaces/superfluid/ISuperfluidToken.sol
// SPDX-License-Identifier: AGPLv3 pragma solidity >= 0.7.0; import { ISuperAgreement } from "./ISuperAgreement.sol"; /** * @title Superfluid's token interface. * * @author Superfluid */ interface ISuperfluidToken { /************************************************************************** * Basic information *************************************************************************/ /** * @dev Get superfluid host contract address */ function getHost() external view returns(address host); /************************************************************************** * 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); /// @dev realtimeBalanceOf with timestamp equals to block timestamp function realtimeBalanceOfNow( address account ) external view returns ( int256 availableBalance, uint256 deposit, uint256 owedDeposit, uint256 timestamp); /** * @dev Check if one account is critical * @param account Account check if is critical by a future time * @param timestamp Time of balance * @return isCritical */ function isAccountCritical( address account, uint256 timestamp ) external view returns(bool isCritical); /** * @dev Check if one account is critical now * @param account Account check if is critical by a future time * @return isCritical */ function isAccountCriticalNow( address account ) external view returns(bool isCritical); /** * @dev Check if one account is solvent * @param account Account check if is solvent by a future time * @param timestamp Time of balance * @return isSolvent */ function isAccountSolvent( address account, uint256 timestamp ) external view returns(bool isSolvent); /** * @dev Check if one account is solvent now * @param account Account check if is solvent now * @return isSolvent */ function isAccountSolventNow( address account ) external view returns(bool isSolvent); /** * @dev 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 creation 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 creation 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 termination 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 * * 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 a 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); /** * @dev Agreement account state updated event * @param agreementClass Contract address of the agreement * @param account Account of the agrement * @param state Agreement state of the account */ event AgreementAccountStateUpdated( address indexed agreementClass, address indexed account, bytes state ); /** * @dev Settle balance from an account by the agreement. * 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 * * Modifiers: * - onlyAgreement */ function settleBalance( address account, int256 delta ) external; /** * @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 */ event AgreementLiquidated( address indexed agreementClass, bytes32 id, address indexed penaltyAccount, address indexed rewardAccount, uint256 rewardAmount ); /** * @dev System bailout occurred (DEPRECATIED BY AgreementLiquidatedBy) * @param bailoutAccount Account that bailout the penalty account * @param bailoutAmount Amount of account bailout */ event Bailout( address indexed bailoutAccount, uint256 bailoutAmount ); /** * @dev Agreement liquidation event (including agent account) * @param agreementClass Contract address of the agreement * @param id Agreement ID * @param liquidatorAccount Account of the agent that performed the liquidation. * @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 * * 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 ); /** * @dev Make liquidation payouts * @param id Agreement ID * @param liquidator Address of the executer of liquidation * @param penaltyAccount Account of the agreement to be penalized * @param rewardAmount Amount of liquidation reward * @param bailoutAmount Amount of account bailout needed * * NOTE: * Liquidation rules: * - If a bailout is required (bailoutAmount > 0) * - the actual reward goes to the liquidator, * - while the reward account becomes the bailout account * - total bailout include: bailout amount + reward amount * * Modifiers: * - onlyAgreement */ function makeLiquidationPayouts ( bytes32 id, address liquidator, address penaltyAccount, uint256 rewardAmount, uint256 bailoutAmount ) 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 host contract //modifier onlyHost() virtual; /// @dev The msg.sender must be a listed agreement. //modifier onlyAgreement() virtual; }
/_openzeppelin/contracts/token/ERC777/IERC777Recipient.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Interface of the ERC777TokensRecipient standard as defined in the EIP. * * Accounts can be notified of {IERC777} tokens being sent to them by having a * contract implement this interface (contract holders can be their own * implementer) and registering it on the * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 global registry]. * * See {IERC1820Registry} and {ERC1820Implementer}. */ interface IERC777Recipient { /** * @dev Called by an {IERC777} token contract whenever tokens are being * moved or created into a registered account (`to`). The type of operation * is conveyed by `from` being the zero address or not. * * This call occurs _after_ the token contract's state is updated, so * {IERC777-balanceOf}, etc., can be used to query the post-operation state. * * This function may revert to prevent the operation from being executed. */ function tokensReceived( address operator, address from, address to, uint256 amount, bytes calldata userData, bytes calldata operatorData ) external; }
/project_/contracts/interfaces/superfluid/ISuperfluidGovernance.sol
// SPDX-License-Identifier: AGPLv3 pragma solidity >= 0.7.0; import { ISuperAgreement } from "./ISuperAgreement.sol"; import { ISuperToken } from "./ISuperToken.sol"; import { ISuperfluidToken } from "./ISuperfluidToken.sol"; import { ISuperfluid } from "./ISuperfluid.sol"; /** * @dev Superfluid's 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 * * 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 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); }
/project_/contracts/interfaces/superfluid/ISuperfluid.sol
// SPDX-License-Identifier: AGPLv3 pragma solidity >= 0.7.0; // This is required by the batchCall and decodeCtx pragma experimental ABIEncoderV2; 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 { SuperAppDefinitions, ContextDefinitions, BatchOperation, 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"; /** * @dev Superfluid host interface. * It is the central contract of the system where super agreement, super app * and super token features are connected together. * * The superfluid host contract is also the entry point for the protocol users, * where batch call and meta transaction are provided for UX improvements. * * @author Superfluid */ interface ISuperfluid { /************************************************************************** * Governance *************************************************************************/ /** * @dev Get the current governace of the Superfluid host */ function getGovernance() external view returns(ISuperfluidGovernance governance); event GovernanceReplaced(ISuperfluidGovernance oldGov, ISuperfluidGovernance newGov); /** * @dev Replace the current governance with a new one */ function replaceGovernance(ISuperfluidGovernance newGov) external; /************************************************************************** * Agreement Whitelisting *************************************************************************/ event AgreementClassRegistered(bytes32 agreementType, address code); /** * @dev Register a new agreement class to the system * @param agreementClassLogic INitial agreement class code * * Modifiers: * - onlyGovernance */ function registerAgreementClass(ISuperAgreement agreementClassLogic) external; event AgreementClassUpdated(bytes32 agreementType, address code); /** * @dev Update code of an agreement class * @param agreementClassLogic New code for the agreement class * * Modifiers: * - onlyGovernance */ function updateAgreementClass(ISuperAgreement agreementClassLogic) external; /** * @dev Check if the agreement class is whitelisted */ 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); /** * @dev Get agreement class */ 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); /** * @dev Create a new bitmask by adding a agreement class to it. * @param bitmap Agreement class bitmap */ function addToAgreementClassesBitmap(uint256 bitmap, bytes32 agreementType) external view returns (uint256 newBitmap); /** * @dev Create a new bitmask by removing a agreement class from it. * @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); event SuperTokenFactoryUpdated(ISuperTokenFactory newFactory); /** * @dev Update super token factory * @param newFactory New factory logic */ function updateSuperTokenFactory(ISuperTokenFactory newFactory) external; event SuperTokenLogicUpdated(ISuperToken indexed token, address code); /** * @dev Update the super token logic to the latest * * NOTE: * - Refer toISuperTokenFactory.Upgradability for expected behaviours. */ function updateSuperTokenLogic(ISuperToken token) external; /************************************************************************** * App Registry *************************************************************************/ /** * @dev App registered event */ event AppRegistered(ISuperApp indexed app); /** * @dev Jail event for the app */ event Jail(ISuperApp indexed app, uint256 reason); /** * @dev Message sender declares it as a super app * @param configWord The super app manifest configuration, flags are defined in * `SuperAppDefinitions` */ function registerApp(uint256 configWord) external; /** * @dev Message sender declares it as a super app, using a registration key * @param configWord The super app manifest configuration, flags are defined in * `SuperAppDefinitions` * @param registrationKey The registration key issued by the governance */ function registerAppWithKey(uint256 configWord, string calldata registrationKey) external; /** * @dev Message sender declares app as a super app * @param configWord The super app manifest configuration, flags are defined in * `SuperAppDefinitions` * NOTE: only factory contracts authorized by governance can register super apps */ 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 White-list the target app for app composition for the source app (msg.sender) * @param targetApp The taget 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 taget 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. *************************************************************************/ function callAppBeforeCallback( ISuperApp app, bytes calldata callData, bool isTermination, bytes calldata ctx ) external // onlyAgreement // isAppActive(app) returns(bytes memory cbdata); function callAppAfterCallback( ISuperApp app, bytes calldata callData, bool isTermination, bytes calldata ctx ) external // onlyAgreement // isAppActive(app) returns(bytes memory appCtx); function appCallbackPush( bytes calldata ctx, ISuperApp app, uint256 appAllowanceGranted, int256 appAllowanceUsed, ISuperfluidToken appAllowanceToken ) external // onlyAgreement returns (bytes memory appCtx); function appCallbackPop( bytes calldata ctx, int256 appAllowanceUsedDelta ) external // onlyAgreement returns (bytes memory newCtx); function ctxUseAllowance( bytes calldata ctx, uint256 appAllowanceWantedMore, int256 appAllowanceUsedDelta ) external // onlyAgreement returns (bytes memory newCtx); function jailApp( bytes calldata ctx, ISuperApp app, uint256 reason ) external // onlyAgreement returns (bytes memory newCtx); /************************************************************************** * 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 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 returns(bytes memory returnedData); /** * @dev Call app action * @param callData The contextual call data. * * NOTE: See callAgreement about contextual call data. */ function callAppAction( ISuperApp app, bytes calldata callData ) external //cleanCtx //isAppActive(app) 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 ABIv2 Encoded memory data of context * * 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 timestsamp 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 // validCtx(ctx) // onlyAgreement(agreementClass) returns (bytes memory newCtx, bytes memory returnedData); function callAppActionWithContext( ISuperApp app, bytes calldata callData, bytes calldata ctx ) external // validCtx(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. 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 don't like it *************************************************************************/ /* /// @dev The current superfluid context is clean. modifier cleanCtx() virtual; /// @dev The superfluid context is valid. modifier validCtx(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; */ }
/project_/contracts/interfaces/superfluid/ISuperTokenFactory.sol
// SPDX-License-Identifier: AGPLv3 pragma solidity >= 0.7.0; import { ISuperToken } from "./ISuperToken.sol"; import { IERC20, ERC20WithTokenInfo } from "../tokens/ERC20WithTokenInfo.sol"; 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; event SuperTokenLogicCreated(ISuperToken indexed tokenLogic); event SuperTokenCreated(ISuperToken indexed token); event CustomSuperTokenCreated(ISuperToken indexed token); }
/project_/contracts/interfaces/superfluid/ISuperToken.sol
// SPDX-License-Identifier: AGPLv3 pragma solidity >= 0.7.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 Superfluid's 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. * * NOTE: SuperToken always uses 18 decimals. * * 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 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`. * * Returns a boolean value indicating whether the operation succeeded. * * 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. * * 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. * * 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 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. * * Returns a boolean value indicating whether the operation succeeded. * * 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}. * * Emits an {Approval} event indicating the updated allowance. * * 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}. * * Emits an {Approval} event indicating the updated allowance. * * 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. * * For super token contracts, this value is 1 always */ function granularity() external view override(IERC777) 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 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}. * * Emits a {Burned} event. * * 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}. * * Emits an {AuthorizedOperator} event. * * 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}. * * Emits a {RevokedOperator} event. * * 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}. * * 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 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}. * * 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 override(IERC777); /************************************************************************** * SuperToken custom token functions *************************************************************************/ /** * @dev Mint new tokens for the account * * Modifiers: * - onlySelf */ function selfMint( address account, uint256 amount, bytes memory userData ) external; /** * @dev Burn existing tokens for the account * * Modifiers: * - onlySelf */ function selfBurn( address account, uint256 amount, bytes memory userData ) 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) * * 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 * * 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. * * 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. * * 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) * * 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) * * 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 }
/project_/contracts/interfaces/superfluid/ISuperApp.sol
// SPDX-License-Identifier: AGPLv3 pragma solidity >= 0.7.0; import { ISuperToken } from "./ISuperToken.sol"; /** * @title Superfluid's app interface. * * NOTE: * - Be fearful of the app jail, when the word permitted is used. * * @author Superfluid */ 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. * * 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. * * 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. * * 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. * * 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. * * 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. * * 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); }
/project_/contracts/interfaces/superfluid/ISuperAgreement.sol
// SPDX-License-Identifier: AGPLv3 pragma solidity >= 0.7.0; import { ISuperfluidToken } from "./ISuperfluidToken.sol"; /** * @title Superfluid's agreement interface. * * @author Superfluid */ interface ISuperAgreement { /** * @dev Initialize the agreement contract */ function initialize() external; /** * @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 Future 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 ); }
/project_/contracts/interfaces/superfluid/Definitions.sol
// SPDX-License-Identifier: AGPLv3 pragma solidity >= 0.7.0; /** * @dev Super app definitions library */ 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; } /** * @dev Context definitions library */ 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); } } /** * @dev Batch operation library */ 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; } library SuperfluidGovernanceConfigs { bytes32 constant internal SUPERFLUID_REWARD_ADDRESS_CONFIG_KEY = keccak256("org.superfluid-finance.superfluid.rewardAddress"); bytes32 constant internal CFAv1_LIQUIDATION_PERIOD_CONFIG_KEY = keccak256("org.superfluid-finance.agreements.ConstantFlowAgreement.v1.liquidationPeriod"); 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)); } }
/project_/contracts/interfaces/agreements/IConstantFlowAgreementV1.sol
// SPDX-License-Identifier: AGPLv3 pragma solidity >= 0.7.0; import { ISuperAgreement } from "../superfluid/ISuperAgreement.sol"; import { ISuperfluidToken } from "../superfluid/ISuperfluidToken.sol"; /** * @dev Superfluid's 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"); } /** * @dev Get the maximum flow rate allowed with the deposit * @param deposit Deposit amount used for creating the flow */ function getMaximumFlowRateFromDeposit( ISuperfluidToken token, uint256 deposit) external view virtual returns (int96 flowRate); /** * @dev Get the deposit required for creating the flow * @param flowRate Flow rate to be tested */ function getDepositRequiredForFlowRate( ISuperfluidToken token, int96 flowRate) external view virtual returns (uint256 deposit); /** * @dev Create a flow betwen sender and receiver. * @param token Super token address. * @param receiver Flow receiver address. * @param flowRate New flow rate in amount per second. * * # App callbacks * * - AgreementCreated * - agreementId - can be used in getFlowByID * - agreementData - abi.encode(address flowSender, address flowReceiver) * * 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); /** * @dev Update the flow rate between sender and receiver. * @param token Super token address. * @param receiver Flow receiver address. * @param flowRate New flow rate in amount per second. * * # App callbacks * * - AgreementUpdated * - agreementId - can be used in getFlowByID * - agreementData - abi.encode(address flowSender, address flowReceiver) * * 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); /** * @dev Get the flow data between `sender` and `receiver`. * @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 ); /** * @dev Get flow data using agreement ID * @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 amount of deposit the flow. * @return owedDeposit The amount of owed deposit 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. */ 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 Flow rate. */ function getNetFlow( ISuperfluidToken token, address account ) external view virtual returns (int96 flowRate); /** * @dev Delete the flow between sender and receiver * @param token Super token address. * @param ctx Context bytes. * @param receiver Flow receiver address. * * # App callbacks * * - AgreementTerminated * - agreementId - can be used in getFlowByID * - agreementData - abi.encode(address flowSender, address flowReceiver) * * 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); /** * @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 flowRate Total flow rate in amount per second for the sender. * @param flowRate 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 ); }
/_openzeppelin/contracts/token/ERC777/IERC777.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <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 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 ); event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData); event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData); event AuthorizedOperator(address indexed operator, address indexed tokenHolder); event RevokedOperator(address indexed operator, address indexed tokenHolder); }
/_openzeppelin/contracts/token/ERC20/IERC20.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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 `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, 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 `sender` to `recipient` 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 sender, address recipient, uint256 amount) external returns (bool); /** * @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); }
/_openzeppelin/contracts/introspection/IERC1820Registry.sol
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Interface of the global ERC1820 Registry, as defined in the * https://eips.ethereum.org/EIPS/eip-1820[EIP]. Accounts may register * implementers for interfaces in this registry, as well as query support. * * Implementers may be shared by multiple accounts, and can also implement more * than a single interface for each account. Contracts can implement interfaces * for themselves, but externally-owned accounts (EOA) must delegate this to a * contract. * * {IERC165} interfaces can also be queried via the registry. * * For an in-depth explanation and source code analysis, see the EIP text. */ interface IERC1820Registry { /** * @dev Sets `newManager` as the manager for `account`. A manager of an * account is able to set interface implementers for it. * * By default, each account is its own manager. Passing a value of `0x0` in * `newManager` will reset the manager to this initial state. * * Emits a {ManagerChanged} event. * * Requirements: * * - the caller must be the current manager for `account`. */ function setManager(address account, address newManager) external; /** * @dev Returns the manager for `account`. * * See {setManager}. */ function getManager(address account) external view returns (address); /** * @dev Sets the `implementer` contract as ``account``'s implementer for * `interfaceHash`. * * `account` being the zero address is an alias for the caller's address. * The zero address can also be used in `implementer` to remove an old one. * * See {interfaceHash} to learn how these are created. * * Emits an {InterfaceImplementerSet} event. * * Requirements: * * - the caller must be the current manager for `account`. * - `interfaceHash` must not be an {IERC165} interface id (i.e. it must not * end in 28 zeroes). * - `implementer` must implement {IERC1820Implementer} and return true when * queried for support, unless `implementer` is the caller. See * {IERC1820Implementer-canImplementInterfaceForAddress}. */ function setInterfaceImplementer(address account, bytes32 _interfaceHash, address implementer) external; /** * @dev Returns the implementer of `interfaceHash` for `account`. If no such * implementer is registered, returns the zero address. * * If `interfaceHash` is an {IERC165} interface id (i.e. it ends with 28 * zeroes), `account` will be queried for support of it. * * `account` being the zero address is an alias for the caller's address. */ function getInterfaceImplementer(address account, bytes32 _interfaceHash) external view returns (address); /** * @dev Returns the interface hash for an `interfaceName`, as defined in the * corresponding * https://eips.ethereum.org/EIPS/eip-1820#interface-name[section of the EIP]. */ function interfaceHash(string calldata interfaceName) external pure returns (bytes32); /** * @notice Updates the cache with whether the contract implements an ERC165 interface or not. * @param account Address of the contract for which to update the cache. * @param interfaceId ERC165 interface for which to update the cache. */ function updateERC165Cache(address account, bytes4 interfaceId) external; /** * @notice Checks whether a contract implements an ERC165 interface or not. * If the result is not cached a direct lookup on the contract address is performed. * If the result is not cached or the cached value is out-of-date, the cache MUST be updated manually by calling * {updateERC165Cache} with the contract address. * @param account Address of the contract to check. * @param interfaceId ERC165 interface to check. * @return True if `account` implements `interfaceId`, false otherwise. */ function implementsERC165Interface(address account, bytes4 interfaceId) external view returns (bool); /** * @notice Checks whether a contract implements an ERC165 interface or not without using nor updating the cache. * @param account Address of the contract to check. * @param interfaceId ERC165 interface to check. * @return True if `account` implements `interfaceId`, false otherwise. */ function implementsERC165InterfaceNoCache(address account, bytes4 interfaceId) external view returns (bool); event InterfaceImplementerSet(address indexed account, bytes32 indexed interfaceHash, address indexed implementer); event ManagerChanged(address indexed account, address indexed newManager); }
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"host_","internalType":"contract ISuperfluid"},{"type":"uint256","name":"minBondDuration_","internalType":"uint256"},{"type":"address","name":"custodian_","internalType":"contract TokenCustodian"}]},{"type":"event","name":"BondIncreased","inputs":[{"type":"address","name":"token","internalType":"contract ISuperToken","indexed":true},{"type":"uint256","name":"additionalBond","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"ExitRateChanged","inputs":[{"type":"address","name":"token","internalType":"contract ISuperToken","indexed":true},{"type":"int96","name":"exitRate","internalType":"int96","indexed":false}],"anonymous":false},{"type":"event","name":"NewPIC","inputs":[{"type":"address","name":"token","internalType":"contract ISuperToken","indexed":true},{"type":"address","name":"pic","internalType":"address","indexed":false},{"type":"uint256","name":"bond","internalType":"uint256","indexed":false},{"type":"int96","name":"exitRate","internalType":"int96","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint64","name":"","internalType":"uint64"}],"name":"ERC777_SEND_GAS_LIMIT","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"changeExitRate","inputs":[{"type":"address","name":"token","internalType":"contract ISuperToken"},{"type":"int96","name":"newExitRate","internalType":"int96"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract TokenCustodian"}],"name":"custodian","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"pic","internalType":"address"}],"name":"getCurrentPIC","inputs":[{"type":"address","name":"token","internalType":"contract ISuperToken"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"pic","internalType":"address"},{"type":"uint256","name":"bond","internalType":"uint256"},{"type":"int96","name":"exitRate","internalType":"int96"}],"name":"getCurrentPICInfo","inputs":[{"type":"address","name":"token","internalType":"contract ISuperToken"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"int96","name":"exitRate","internalType":"int96"}],"name":"getDefaultExitRateFor","inputs":[{"type":"address","name":"","internalType":"contract ISuperToken"},{"type":"uint256","name":"bondAmount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"int96","name":"exitRate","internalType":"int96"}],"name":"getMaxExitRateFor","inputs":[{"type":"address","name":"","internalType":"contract ISuperToken"},{"type":"uint256","name":"bondAmount","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"minBondDuration","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"tokensReceived","inputs":[{"type":"address","name":"","internalType":"address"},{"type":"address","name":"from","internalType":"address"},{"type":"address","name":"","internalType":"address"},{"type":"uint256","name":"amount","internalType":"uint256"},{"type":"bytes","name":"userData","internalType":"bytes"},{"type":"bytes","name":"","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdrawFundsInCustody","inputs":[{"type":"address","name":"token","internalType":"contract ISuperToken"}]}]
Deployed ByteCode
0x608060405234801561001057600080fd5b506004361061009d5760003560e01c8063375b74c311610066578063375b74c31461026357806360dfa6951461026b5780636da8d05414610285578063b8a14033146102ab578063bf8903dd146102d75761009d565b806223de29146100a257806302f3c6c51461018a5780630797e3e7146101b957806316e23b9f146101de5780633629106314610221575b600080fd5b610188600480360360c08110156100b857600080fd5b6001600160a01b03823581169260208101358216926040820135909216916060820135919081019060a081016080820135600160201b8111156100fa57600080fd5b82018360208201111561010c57600080fd5b803590602001918460018302840111600160201b8311171561012d57600080fd5b919390929091602081019035600160201b81111561014a57600080fd5b82018360208201111561015c57600080fd5b803590602001918460018302840111600160201b8311171561017d57600080fd5b509092509050610328565b005b610188600480360360408110156101a057600080fd5b506001600160a01b038135169060200135600b0b6103d5565b6101c1610ca1565b6040805167ffffffffffffffff9092168252519081900360200190f35b61020a600480360360408110156101f457600080fd5b506001600160a01b038135169060200135610cc5565b60408051600b9290920b8252519081900360200190f35b6102476004803603602081101561023757600080fd5b50356001600160a01b0316610cfb565b604080516001600160a01b039092168252519081900360200190f35b610247610d19565b610273610d28565b60408051918252519081900360200190f35b6101886004803603602081101561029b57600080fd5b50356001600160a01b0316610d4c565b61020a600480360360408110156102c157600080fd5b506001600160a01b038135169060200135610dbb565b6102fd600480360360208110156102ed57600080fd5b50356001600160a01b0316610de6565b604080516001600160a01b0390941684526020840192909252600b0b82820152519081900360600190f35b336000818152602081905260409020546001600160a01b0389811691161461038a576000841561036c578585602081101561036257600080fd5b5035600b0b610376565b6103768288610cc5565b9050610384828a8984610ed7565b506103ca565b6040805187815290516001600160a01b038316917fb9c1b85a7ee70d95c61aca7cda03ef957abc5265a191ca74cc335faf59409566919081900360200190a25b505050505050505050565b6001600160a01b038083166000908152602081905260409020541633811461043d576040805162461bcd60e51b81526020600482015260166024820152751513d1d04e881bdb9b1e48141250c8185b1b1bddd95960521b604482015290519081900360640190fd5b600082600b0b12156104805760405162461bcd60e51b8152600401808060200182810382526023815260200180611a1c6023913960400191505060405180910390fd5b61048983611974565b7f0000000000000000000000000000000000000000000000000000000000093a8083600b0b0211156104fc576040805162461bcd60e51b81526020600482015260176024820152760a89e8e827440caf0d2e8a4c2e8ca40e8dede40d0d2ced604b1b604482015290519081900360640190fd5b60408051631cd43d1160e31b81526001600160a01b038581166004830152306024830152838116604483015291516000927f000000000000000000000000ebda4cef883a7b12c4e669ebc58927fba8447c7d169163e6a1e888916064808301926080929190829003018186803b15801561057557600080fd5b505afa158015610589573d6000803e3d6000fd5b505050506040513d608081101561059f57600080fd5b506020015190506000600b82900b1380156105bd5750600083600b0b135b156108cb576001600160a01b037f0000000000000000000000002dfe937cd98ab92e59cf3139138f18c823a4efe7166339255d5b7f000000000000000000000000ebda4cef883a7b12c4e669ebc58927fba8447c7d6328104d3160e11b8786886000805b506040519080825280601f01601f19166020018201604052801561064c576020820181803683370190505b5060405160240180856001600160a01b03168152602001846001600160a01b0316815260200183600b0b815260200180602001828103825283818151815260200191508051906020019080838360005b838110156106b457818101518382015260200161069c565b50505050905090810190601f1680156106e15780820380516001836020036101000a031916815260200191505b5060408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199a8b16178152905160e08c901b90991689526001600160a01b038a1660048a01908152606060248b01908152835160648c01528351939a919950975060448101965060840194509250905080838360005b8381101561077357818101518382015260200161075b565b50505050905090810190601f1680156107a05780820380516001836020036101000a031916815260200191505b508381038252600281526020018061060f60f31b815250602001945050505050600060405180830381600087803b1580156107da57600080fd5b505af11580156107ee573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561081757600080fd5b8101908080516040519392919084600160201b82111561083657600080fd5b90830190602082018581111561084b57600080fd5b8251600160201b81118282018810171561086457600080fd5b82525081516020918201929091019080838360005b83811015610891578181015183820152602001610879565b50505050905090810190601f1680156108be5780820380516001836020036101000a031916815260200191505b5060405250505050610c57565b80600b0b60001480156108e15750600083600b0b135b15610949576001600160a01b037f0000000000000000000000002dfe937cd98ab92e59cf3139138f18c823a4efe7166339255d5b7f000000000000000000000000ebda4cef883a7b12c4e669ebc58927fba8447c7d63317e182f60e11b878688600080610621565b600081600b0b13801561095f575082600b0b6000145b15610c5757604080516000808252602082019092527f0000000000000000000000002dfe937cd98ab92e59cf3139138f18c823a4efe76001600160a01b0316916339255d5b917f000000000000000000000000ebda4cef883a7b12c4e669ebc58927fba8447c7d91635a5999e360e11b918991309189915060405160240180856001600160a01b03168152602001846001600160a01b03168152602001836001600160a01b0316815260200180602001828103825283818151815260200191508051906020019080838360005b83811015610a44578181015183820152602001610a2c565b50505050905090810190601f168015610a715780820380516001836020036101000a031916815260200191505b5060408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199a8b16178152905160e08c901b90991689526001600160a01b038a1660048a01908152606060248b01908152835160648c01528351939a919950975060448101965060840194509250905080838360005b83811015610b03578181015183820152602001610aeb565b50505050905090810190601f168015610b305780820380516001836020036101000a031916815260200191505b508381038252600281526020018061060f60f31b815250602001945050505050600060405180830381600087803b158015610b6a57600080fd5b505af1158015610b7e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526020811015610ba757600080fd5b8101908080516040519392919084600160201b821115610bc657600080fd5b908301906020820185811115610bdb57600080fd5b8251600160201b811182820188101715610bf457600080fd5b82525081516020918201929091019080838360005b83811015610c21578181015183820152602001610c09565b50505050905090810190601f168015610c4e5780820380516001836020036101000a031916815260200191505b50604052505050505b836001600160a01b03167f0988aefa675e81e1db7fca08264db5dc2a1cc2a604f2a78d902a9747146a5671846040518082600b0b815260200191505060405180910390a250505050565b7f00000000000000000000000000000000000000000000000000000000002dc6c081565b60007f0000000000000000000000000000000000000000000000000000000000093a806004028281610cf357fe5b049392505050565b6001600160a01b039081166000908152602081905260409020541690565b6001546001600160a01b031681565b7f0000000000000000000000000000000000000000000000000000000000093a8081565b60015460408051634e7eee1b60e11b81526001600160a01b03848116600483015233602483015291519190921691639cfddc3691604480830192600092919082900301818387803b158015610da057600080fd5b505af1158015610db4573d6000803e3d6000fd5b5050505050565b60007f0000000000000000000000000000000000000000000000000000000000093a808281610cf357fe5b6001600160a01b03818116600081815260208190526040808220548151631cd43d1160e31b8152600481019490945230602485015284166044840152519092839283927f000000000000000000000000ebda4cef883a7b12c4e669ebc58927fba8447c7d9092169163e6a1e88891606480820192608092909190829003018186803b158015610e7457600080fd5b505afa158015610e88573d6000803e3d6000fd5b505050506040513d6080811015610e9e57600080fd5b506020908101516001600160a01b0380871660009081529283905260409092205490925016610ecc85611974565b925092509193909250565b6001600160a01b038416600090815260208190526040902054600160a01b900460ff1615610f4c576040805162461bcd60e51b815260206004820152601c60248201527f544f47413a207265656e7472616e6379206e6f7420616c6c6f77656400000000604482015290519081900360640190fd5b600081600b0b1215610f8f5760405162461bcd60e51b8152600401808060200182810382526023815260200180611a1c6023913960400191505060405180910390fd5b817f0000000000000000000000000000000000000000000000000000000000093a8082600b0b021115611003576040805162461bcd60e51b81526020600482015260176024820152760a89e8e827440caf0d2e8a4c2e8ca40e8dede40d0d2ced604b1b604482015290519081900360640190fd5b60008261100f86611974565b03905080831161105a576040805162461bcd60e51b8152602060048201526011602482015270544f47413a2062696420746f6f206c6f7760781b604482015290519081900360640190fd5b6001600160a01b03808616600081815260208190526040808220805460ff60a01b198116600160a01b179091558151631cd43d1160e31b815260048101949094523060248501528416604484018190529051909391927f000000000000000000000000ebda4cef883a7b12c4e669ebc58927fba8447c7d9092169163e6a1e888916064808301926080929190829003018186803b1580156110fa57600080fd5b505afa15801561110e573d6000803e3d6000fd5b505050506040513d608081101561112457600080fd5b506020015190506000600b82900b131561142b57604080516000808252602082019092527f0000000000000000000000002dfe937cd98ab92e59cf3139138f18c823a4efe76001600160a01b0316916339255d5b917f000000000000000000000000ebda4cef883a7b12c4e669ebc58927fba8447c7d91635a5999e360e11b918c91309189915060405160240180856001600160a01b03168152602001846001600160a01b03168152602001836001600160a01b0316815260200180602001828103825283818151815260200191508051906020019080838360005b83811015611218578181015183820152602001611200565b50505050905090810190601f1680156112455780820380516001836020036101000a031916815260200191505b5060408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199a8b16178152905160e08c901b90991689526001600160a01b038a1660048a01908152606060248b01908152835160648c01528351939a919950975060448101965060840194509250905080838360005b838110156112d75781810151838201526020016112bf565b50505050905090810190601f1680156113045780820380516001836020036101000a031916815260200191505b508381038252600281526020018061060f60f31b815250602001945050505050600060405180830381600087803b15801561133e57600080fd5b505af1158015611352573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561137b57600080fd5b8101908080516040519392919084600160201b82111561139a57600080fd5b9083019060208201858111156113af57600080fd5b8251600160201b8111828201881017156113c857600080fd5b82525081516020918201929091019080838360005b838110156113f55781810151838201526020016113dd565b50505050905090810190601f1680156114225780820380516001836020036101000a031916815260200191505b50604052505050505b6001600160a01b038216156115db5760408051634decdde360e11b81526001600160a01b03848116600483015260248201869052606060448301526002606483015261060f60f31b6084830152915191891691639bd9bbc69167ffffffffffffffff7f00000000000000000000000000000000000000000000000000000000002dc6c0169160a480830192600092919082900301818388803b1580156114d057600080fd5b5087f1935050505080156114e2575060015b6115db57600154604080516001600160a01b0385811660208084019190915283518084038201815283850194859052634decdde360e11b9094529381166044830181815260648401899052606060848501908152855160a48601528551938e1696639bd9bbc69693958b9560c49091019185019080838360005b8381101561157457818101518382015260200161155c565b50505050905090810190601f1680156115a15780820380516001836020036101000a031916815260200191505b50945050505050600060405180830381600087803b1580156115c257600080fd5b505af11580156115d6573d6000803e3d6000fd5b505050505b6001600160a01b03878116600090815260208190526040812080546001600160a01b03191692891692909217909155600b85900b131561190257604080516000808252602082019092527f0000000000000000000000002dfe937cd98ab92e59cf3139138f18c823a4efe76001600160a01b0316916339255d5b917f000000000000000000000000ebda4cef883a7b12c4e669ebc58927fba8447c7d9163317e182f60e11b918c918c918b915060405160240180856001600160a01b03168152602001846001600160a01b0316815260200183600b0b815260200180602001828103825283818151815260200191508051906020019080838360005b838110156116ef5781810151838201526020016116d7565b50505050905090810190601f16801561171c5780820380516001836020036101000a031916815260200191505b5060408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199a8b16178152905160e08c901b90991689526001600160a01b038a1660048a01908152606060248b01908152835160648c01528351939a919950975060448101965060840194509250905080838360005b838110156117ae578181015183820152602001611796565b50505050905090810190601f1680156117db5780820380516001836020036101000a031916815260200191505b508381038252600281526020018061060f60f31b815250602001945050505050600060405180830381600087803b15801561181557600080fd5b505af1158015611829573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561185257600080fd5b8101908080516040519392919084600160201b82111561187157600080fd5b90830190602082018581111561188657600080fd5b8251600160201b81118282018810171561189f57600080fd5b82525081516020918201929091019080838360005b838110156118cc5781810151838201526020016118b4565b50505050905090810190601f1680156118f95780820380516001836020036101000a031916815260200191505b50604052505050505b6001600160a01b0380881660008181526020818152604091829020805460ff60a01b191690558151938a1684528301889052600b87900b838201525190917f836808e57755d5535898b7203c7d68b1bfb2701b1943ecb133c675e0d0078015919081900360600190a250505050505050565b6000806000836001600160a01b0316632ec8eec7306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060806040518083038186803b1580156119c657600080fd5b505afa1580156119da573d6000803e3d6000fd5b505050506040513d60808110156119f057600080fd5b5080516020909101519092509050600081830113611a0f576000611a13565b8082015b94935050505056fe544f47413a206e65676174697665206578697452617465206e6f7420616c6c6f776564a264697066735822122014ae35bf1aeb42a36c3a695f63745f20d13e2aa3768d2a82a458438d637dc44a64736f6c63430007060033