Polygon Sponsored slots available. Book your slot here!
Contract Overview
My Name Tag:
Not Available, login to update
[ Download CSV Export ]
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
RicochetLaunchpad
Compiler Version
v0.8.13+commit.abaa5c0e
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; pragma abicoder v2; // import "hardhat/console.sol"; import { ISuperfluid, ISuperToken, ISuperApp, ISuperAgreement, SuperAppDefinitions } from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol";//"@superfluid-finance/ethereum-monorepo/packages/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol"; import { IConstantFlowAgreementV1 } from "@superfluid-finance/ethereum-contracts/contracts/interfaces/agreements/IConstantFlowAgreementV1.sol"; import { IInstantDistributionAgreementV1 } from "@superfluid-finance/ethereum-contracts/contracts/interfaces/agreements/IInstantDistributionAgreementV1.sol"; import { SuperAppBase } from "@superfluid-finance/ethereum-contracts/contracts/apps/SuperAppBase.sol"; import { Ownable } from "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "./RicochetLaunchpadStorage.sol"; import "./RicochetLaunchpadHelper.sol"; import "../referral/IREXReferral.sol"; contract RicochetLaunchpad is Ownable, SuperAppBase { // TODO: uint256 public constant RATE_PERCISION = 1000000; using SafeERC20 for ERC20; using RicochetLaunchpadHelper for RicochetLaunchpadStorage.RicochetLaunchpad; using RicochetLaunchpadStorage for RicochetLaunchpadStorage.RicochetLaunchpad; RicochetLaunchpadStorage.RicochetLaunchpad internal _launchpad; IREXReferral internal referrals; event UpdatedStream(address from, int96 newRate, int96 totalInflow); constructor( ISuperfluid host, IConstantFlowAgreementV1 cfa, IInstantDistributionAgreementV1 ida, string memory registrationKey, IREXReferral _rexReferral ) { require(address(host) != address(0), "host"); require(address(cfa) != address(0), "cfa"); require(address(ida) != address(0), "ida"); require(!host.isApp(ISuperApp(msg.sender)), "owner SA"); _launchpad.host = host; _launchpad.cfa = cfa; _launchpad.ida = ida; referrals = _rexReferral; uint256 configWord = SuperAppDefinitions.APP_LEVEL_FINAL | SuperAppDefinitions.BEFORE_AGREEMENT_CREATED_NOOP | SuperAppDefinitions.BEFORE_AGREEMENT_UPDATED_NOOP | SuperAppDefinitions.BEFORE_AGREEMENT_TERMINATED_NOOP; if(bytes(registrationKey).length > 0) { _launchpad.host.registerAppWithKey(configWord, registrationKey); } else { _launchpad.host.registerApp(configWord); } } function initialize( ISuperToken inputToken, ISuperToken outputToken, address originator, address beneficiary, uint256 outputRate, uint128 feeRate) external { require(address(inputToken) != address(0) && address(_launchpad.inputToken) == address(0) , "inputToken"); require(address(outputToken) != address(0) && address(_launchpad.outputToken) == address(0), "outputToken"); require(address(originator) != address(0), "originator"); require(address(beneficiary) != address(0), "beneficiary"); _launchpad.inputToken = inputToken; _launchpad.outputToken = outputToken; _launchpad.feeRate = feeRate; _launchpad.outputIndexId = 0; _launchpad.outputRate = outputRate; _launchpad.owner = owner(); _launchpad.originator = originator; _launchpad.beneficiary = beneficiary; // Set up the IDA for sending tokens back _launchpad._createIndex(_launchpad.outputIndexId, _launchpad.outputToken); _launchpad.lastDistributionAt = block.timestamp; } function _registerReferral(bytes memory _ctx, address _shareholder) internal { require(referrals.addressToAffiliate(_shareholder) == 0, "noAffiliates"); ISuperfluid.Context memory decompiledContext = _launchpad.host.decodeCtx(_ctx); string memory affiliateId; if (decompiledContext.userData.length > 0) { (affiliateId) = abi.decode(decompiledContext.userData, (string)); } else { affiliateId = ""; } referrals.safeRegisterCustomer(_shareholder, affiliateId); } /************************************************************************** * Stream Exchange Logic *************************************************************************/ /// @dev If a new stream is opened, or an existing one is opened function _updateOutflow(bytes calldata ctx, bytes calldata agreementData, bool doDistributeFirst) private returns (bytes memory newCtx) { newCtx = ctx; (, , uint128 totalUnitsApproved, uint128 totalUnitsPending) = _launchpad.ida.getIndex( _launchpad.outputToken, address(this), _launchpad.outputIndexId); if (doDistributeFirst && totalUnitsApproved + totalUnitsPending > 0 && _launchpad.inputToken.balanceOf(address(this)) > 0) { newCtx = _launchpad._distribute(newCtx); } (address requester, address flowReceiver) = abi.decode(agreementData, (address, address)); require(flowReceiver == address(this), "!appflow"); int96 appFlowRate = _launchpad.cfa.getNetFlow(_launchpad.inputToken, address(this)); (, int96 requesterFlowRate, , ) = _launchpad.cfa.getFlow(_launchpad.inputToken, requester, address(this)); // Make sure the requester has at least 8 hours of balance to stream require(int(_launchpad.inputToken.balanceOf(requester)) >= requesterFlowRate * 8 hours, "!enoughTokens"); require(requesterFlowRate >= 0, "!negativeRates"); address affiliate = referrals.getAffiliateAddress(requester); if(affiliate != address(0)){ // affiliate and admin share 50/50 2% of requesterFlowRate. int96 affiliateShares = requesterFlowRate / 100 * 2; newCtx = _launchpad._updateSubscriptionWithContext(newCtx, _launchpad.outputIndexId, affiliate, uint128(uint(int(affiliateShares / 2))), _launchpad.outputToken); newCtx = _launchpad._updateSubscriptionWithContext(newCtx, _launchpad.outputIndexId, owner(), uint128(uint(int(affiliateShares / 2))), _launchpad.outputToken); // take 2% off of requesterFlowRate if they have an affiliate newCtx = _launchpad._updateSubscriptionWithContext(newCtx, _launchpad.outputIndexId, requester, uint128(uint(int(requesterFlowRate - affiliateShares))), _launchpad.outputToken); } else { newCtx = _launchpad._updateSubscriptionWithContext(newCtx, _launchpad.outputIndexId, requester, uint128(uint(int(requesterFlowRate))), _launchpad.outputToken); } emit UpdatedStream(requester, requesterFlowRate, appFlowRate); } function distribute() external { _launchpad._distribute(new bytes(0)); } function closeStream(address streamer) public { _launchpad._closeStream(streamer); } function emergencyCloseStream(address streamer) public { _launchpad._emergencyCloseStream(streamer); } function emergencyDrain() public { _launchpad._emergencyDrain(); } function setFeeRate(uint128 feeRate) external onlyOwner { _launchpad.feeRate = feeRate; } function isAppJailed() external view returns (bool) { return _launchpad.host.isAppJailed(this); } function getIDAShares(uint32 index, address streamer) external view returns (bool exist, bool approved, uint128 units, uint256 pendingDistribution) { (exist, approved, units, pendingDistribution) = _launchpad.ida.getSubscription( _launchpad.outputToken, address(this), _launchpad.outputIndexId, streamer); } function getSharePrice() external view returns (uint256) { return _launchpad.lastSharePrice; } function getInputToken() external view returns (ISuperToken) { return _launchpad.inputToken; } function getOutputToken() external view returns (ISuperToken) { return _launchpad.outputToken; } function getOutputIndexId() external view returns (uint32) { return _launchpad.outputIndexId; } function getOutputRate() external view returns (uint256) { return _launchpad.outputRate; } function getTotalInflow() external view returns (int96) { return _launchpad.cfa.getNetFlow(_launchpad.inputToken, address(this)); } function getLastDistributionAt() external view returns (uint256) { return _launchpad.lastDistributionAt; } function getOwner() external view returns (address) { return _launchpad.owner; } function getFeeRate() external view returns (uint128) { return _launchpad.feeRate; } function getStreamRate(address streamer) external view returns (int96 requesterFlowRate) { (, requesterFlowRate, , ) = _launchpad.cfa.getFlow(_launchpad.inputToken, streamer, address(this)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. * NOTE: Override this to add changing the */ function transferOwnership(address newOwner) public virtual override onlyOwner { super.transferOwnership(newOwner); _launchpad.owner = newOwner; } /************************************************************************** * SuperApp callbacks *************************************************************************/ function afterAgreementCreated( ISuperToken _superToken, address _agreementClass, bytes32, // _agreementId, bytes calldata _agreementData, bytes calldata ,// _cbdata, bytes calldata _ctx ) external override onlyExpected(_superToken, _agreementClass) onlyHost returns (bytes memory newCtx) { if (!_launchpad._isInputToken(_superToken) || !_launchpad._isCFAv1(_agreementClass)) return _ctx; (address requester) = abi.decode(_agreementData, (address)); _registerReferral(_ctx, requester); return _updateOutflow(_ctx, _agreementData, true); } function afterAgreementUpdated( ISuperToken _superToken, address _agreementClass, bytes32 ,//_agreementId, bytes calldata _agreementData, bytes calldata ,//_cbdata, bytes calldata _ctx ) external override onlyExpected(_superToken, _agreementClass) onlyHost returns (bytes memory newCtx) { if (!_launchpad._isInputToken(_superToken) || !_launchpad._isCFAv1(_agreementClass)) return _ctx; return _updateOutflow(_ctx, _agreementData, true); } function afterAgreementTerminated( ISuperToken _superToken, address _agreementClass, bytes32 ,//_agreementId, bytes calldata _agreementData, bytes calldata ,//_cbdata, bytes calldata _ctx ) external override onlyHost returns (bytes memory newCtx) { console.log("afterAgreementTerminated"); // According to the app basic law, we should never revert in a termination callback if (!_launchpad._isInputToken(_superToken) || !_launchpad._isCFAv1(_agreementClass)) return _ctx; // Skip distribution when terminating to avoid reverts return _updateOutflow(_ctx, _agreementData, false); } modifier onlyHost() { require(msg.sender == address(_launchpad.host), "one host"); _; } modifier onlyExpected(ISuperToken superToken, address agreementClass) { if (_launchpad._isCFAv1(agreementClass)) { require(_launchpad._isInputToken(superToken), "!inputAccepted"); } else if (_launchpad._isIDAv1(agreementClass)) { require(_launchpad._isOutputToken(superToken), "!outputAccepted"); } _; } }
// 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; */ }
// 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 ); }
// SPDX-License-Identifier: AGPLv3 pragma solidity >= 0.7.0; import { ISuperAgreement } from "../superfluid/ISuperAgreement.sol"; import { ISuperfluidToken } from "../superfluid/ISuperfluidToken.sol"; /** * @title Superfluid's instant distribution agreement interface. * * @author Superfluid * * Notes: * - A publisher can create as many as indeces as possibily identifiable with `indexId`. * - `indexId` is deliberately limited to 32 bits, to avoid the chance for sha-3 collision. * Despite knowing sha-3 collision is only theoratical. * - A publisher can create subscription to an index for any subscriber. * - A subscription consists of: * - The index it subscribes to. * - Number of units subscribed. * - An index consists of: * - Current value as `uint128 indexValue`. * - Total units of the approved subscriptions as `uint128 totalUnitsApproved`. * - Total units of the non approved subscription as `uint128 totalUnitsPending`. * - A publisher can update index with new value that doesn't decrease. * - A publisher can update subscription with any number of units. * - A publisher or a subscriber can delete subscription and reset units to zero. * - A subscriber must approve the index in order to receive distributions from the publisher * each time the index is updated. * - The amount distributed is $$\Delta{index} * units$$ * - Distributions to a non approved subscription stays in the publisher's deposit until: * - the subscriber approve the subscription (side effect), * - the publisher update the subscription (side effect), * - the subscriber delete the subscription even if it is never approved (side effect), * - or the subscriber can explicitly claim them. */ abstract contract IInstantDistributionAgreementV1 is ISuperAgreement { /// @dev ISuperAgreement.agreementType implementation function agreementType() external override pure returns (bytes32) { return keccak256("org.superfluid-finance.agreements.InstantDistributionAgreement.v1"); } /************************************************************************** * Index operations *************************************************************************/ /** * @dev Create a new index for the publisher. * @param token Super token address. * @param indexId Id of the index. * * # App callbacks * * None */ function createIndex( ISuperfluidToken token, uint32 indexId, bytes calldata ctx) external virtual returns(bytes memory newCtx); event IndexCreated( ISuperfluidToken indexed token, address indexed publisher, uint32 indexed indexId, bytes userData); /** * @dev Query the data of a index. * @param token Super token address. * @param publisher The publisher of the index. * @param indexId Id of the index. * @return exist Does the index exist. * @return indexValue Value of the current index. * @return totalUnitsApproved Total units approved for the index. * @return totalUnitsPending Total units pending approval for the index. */ function getIndex( ISuperfluidToken token, address publisher, uint32 indexId) external view virtual returns( bool exist, uint128 indexValue, uint128 totalUnitsApproved, uint128 totalUnitsPending); /** * @dev Calculate actual distribution amount * @param token Super token address. * @param publisher The publisher of the index. * @param indexId Id of the index. * @param amount The amount of tokens desired to be distributed. */ function calculateDistribution( ISuperfluidToken token, address publisher, uint32 indexId, uint256 amount) external view virtual returns( uint256 actualAmount, uint128 newIndexValue); /** * @dev Update index value of an index. * @param token Super token address. * @param indexId Id of the index. * @param indexValue Value of the index. * * # App callbacks * * None */ function updateIndex( ISuperfluidToken token, uint32 indexId, uint128 indexValue, bytes calldata ctx) external virtual returns(bytes memory newCtx); event IndexUpdated( ISuperfluidToken indexed token, address indexed publisher, uint32 indexed indexId, uint128 oldIndexValue, uint128 newIndexValue, uint128 totalUnitsPending, uint128 totalUnitsApproved, bytes userData); /** * @dev Distribute tokens through the index. * @param token Super token address. * @param indexId Id of the index. * @param amount The amount of tokens desired to be distributed. * * NOTE: * - This is a convenient version of updateIndex. It adds to the index * a delta that equals to `amount / totalUnits`. * - The actual amount distributed could be obtained via * `calculateDistribution`. This is due to precision error with index * value and units data range. * * # App callbacks * * None */ function distribute( ISuperfluidToken token, uint32 indexId, uint256 amount, bytes calldata ctx) external virtual returns(bytes memory newCtx); /************************************************************************** * Subscription operations *************************************************************************/ /** * @dev Approve the subscription of an index. * @param token Super token address. * @param publisher The publisher of the index. * @param indexId Id of the index. * * # App callbacks * * - if subscription exist * - AgreementCreated callback to the publisher: * - agreementId is for the subscription * - if subscription does not exist * - AgreementUpdated callback to the publisher: * - agreementId is for the subscription */ function approveSubscription( ISuperfluidToken token, address publisher, uint32 indexId, bytes calldata ctx) external virtual returns(bytes memory newCtx); event IndexSubscribed( ISuperfluidToken indexed token, address indexed publisher, uint32 indexed indexId, address subscriber, bytes userData); event SubscriptionApproved( ISuperfluidToken indexed token, address indexed subscriber, address publisher, uint32 indexId, bytes userData); /** * @dev Revoke the subscription of an index. * @param token Super token address. * @param publisher The publisher of the index. * @param indexId Id of the index. * * # App callbacks * - AgreementUpdated callback to the publisher: * - agreementId is for the subscription */ function revokeSubscription( ISuperfluidToken token, address publisher, uint32 indexId, bytes calldata ctx) external virtual returns(bytes memory newCtx); event IndexUnsubscribed( ISuperfluidToken indexed token, address indexed publisher, uint32 indexed indexId, address subscriber, bytes userData); event SubscriptionRevoked( ISuperfluidToken indexed token, address indexed subscriber, address publisher, uint32 indexId, bytes userData); /** * @dev Update the nuber of units of a subscription. * @param token Super token address. * @param indexId Id of the index. * @param subscriber The subscriber of the index. * @param units Number of units of the subscription. * * # App callbacks * * - if subscription exist * - AgreementCreated callback to the subscriber: * - agreementId is for the subscription * - if subscription does not exist * - AgreementUpdated callback to the subscriber: * - agreementId is for the subscription */ function updateSubscription( ISuperfluidToken token, uint32 indexId, address subscriber, uint128 units, bytes calldata ctx) external virtual returns(bytes memory newCtx); event IndexUnitsUpdated( ISuperfluidToken indexed token, address indexed publisher, uint32 indexed indexId, address subscriber, uint128 units, bytes userData); event SubscriptionUnitsUpdated( ISuperfluidToken indexed token, address indexed subscriber, address publisher, uint32 indexId, uint128 units, bytes userData); /** * @dev Get data of a subscription * @param token Super token address. * @param publisher The publisher of the index. * @param indexId Id of the index. * @param subscriber The subscriber of the index. * @return exist Does the subscription exist? * @return approved Is the subscription approved? * @return units Units of the suscription. * @return pendingDistribution Pending amount of tokens to be distributed for unapproved subscription. */ function getSubscription( ISuperfluidToken token, address publisher, uint32 indexId, address subscriber) external view virtual returns( bool exist, bool approved, uint128 units, uint256 pendingDistribution ); /** * @dev Get data of a subscription by agreement ID * @param token Super token address. * @param agreementId The agreement ID. * @return publisher The publisher of the index. * @return indexId Id of the index. * @return approved Is the subscription approved? * @return units Units of the suscription. * @return pendingDistribution Pending amount of tokens to be distributed for unapproved subscription. */ function getSubscriptionByID( ISuperfluidToken token, bytes32 agreementId) external view virtual returns( address publisher, uint32 indexId, bool approved, uint128 units, uint256 pendingDistribution ); /** * @dev List subscriptions of an user. * @param token Super token address. * @param subscriber The user, a subscriber. * @return publishers Publishers of the subcriptions. * @return indexIds Indexes of the subscriptions. * @return unitsList Units of the subscriptions. */ function listSubscriptions( ISuperfluidToken token, address subscriber) external view virtual returns( address[] memory publishers, uint32[] memory indexIds, uint128[] memory unitsList); /** * @dev Delete the subscription of an user. * @param token Super token address. * @param publisher The publisher of the index. * @param indexId Id of the index. * @param subscriber The user, a subscriber. * * # App callbacks * * - if the subscriber called it * - AgreementTerminated callback to the publsiher: * - agreementId is for the subscription * - if the publisher called it * - AgreementTerminated callback to the subscriber: * - agreementId is for the subscription */ function deleteSubscription( ISuperfluidToken token, address publisher, uint32 indexId, address subscriber, bytes calldata ctx) external virtual returns(bytes memory newCtx); /** * @dev Claim pending distributions. * @param token Super token address. * @param publisher The publisher of the index. * @param indexId Id of the index. * @param subscriber The user, a subscriber. * * The subscription should not exist yet. * * # App callbacks * * - AgreementUpdated callback to the publisher: * - agreementId is for the subscription */ function claim( ISuperfluidToken token, address publisher, uint32 indexId, address subscriber, bytes calldata ctx) external virtual returns(bytes memory newCtx); event IndexDistributionClaimed( ISuperfluidToken indexed token, address indexed publisher, uint32 indexed indexId, address subscriber, uint256 amount); event SubscriptionDistributionClaimed( ISuperfluidToken indexed token, address indexed subscriber, address publisher, uint32 indexId, uint256 amount); }
// SPDX-License-Identifier: AGPLv3 pragma solidity >= 0.7.0; import { ISuperfluid, ISuperToken, ISuperApp, SuperAppDefinitions } from "../interfaces/superfluid/ISuperfluid.sol"; abstract contract SuperAppBase is ISuperApp { function beforeAgreementCreated( ISuperToken /*superToken*/, address /*agreementClass*/, bytes32 /*agreementId*/, bytes calldata /*agreementData*/, bytes calldata /*ctx*/ ) external view virtual override returns (bytes memory /*cbdata*/) { revert("Unsupported callback - Before Agreement Created"); } function afterAgreementCreated( ISuperToken /*superToken*/, address /*agreementClass*/, bytes32 /*agreementId*/, bytes calldata /*agreementData*/, bytes calldata /*cbdata*/, bytes calldata /*ctx*/ ) external virtual override returns (bytes memory /*newCtx*/) { revert("Unsupported callback - After Agreement Created"); } function beforeAgreementUpdated( ISuperToken /*superToken*/, address /*agreementClass*/, bytes32 /*agreementId*/, bytes calldata /*agreementData*/, bytes calldata /*ctx*/ ) external view virtual override returns (bytes memory /*cbdata*/) { revert("Unsupported callback - Before Agreement updated"); } function afterAgreementUpdated( ISuperToken /*superToken*/, address /*agreementClass*/, bytes32 /*agreementId*/, bytes calldata /*agreementData*/, bytes calldata /*cbdata*/, bytes calldata /*ctx*/ ) external virtual override returns (bytes memory /*newCtx*/) { revert("Unsupported callback - After Agreement Updated"); } function beforeAgreementTerminated( ISuperToken /*superToken*/, address /*agreementClass*/, bytes32 /*agreementId*/, bytes calldata /*agreementData*/, bytes calldata /*ctx*/ ) external view virtual override returns (bytes memory /*cbdata*/) { revert("Unsupported callback - Before Agreement Terminated"); } function afterAgreementTerminated( ISuperToken /*superToken*/, address /*agreementClass*/, bytes32 /*agreementId*/, bytes calldata /*agreementData*/, bytes calldata /*cbdata*/, bytes calldata /*ctx*/ ) external virtual override returns (bytes memory /*newCtx*/) { revert("Unsupported callback - After Agreement Terminated"); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/ERC20.sol) pragma solidity ^0.8.0; import "./IERC20.sol"; import "./extensions/IERC20Metadata.sol"; import "../../utils/Context.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20, IERC20Metadata { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @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 this function is * overridden; * * 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() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * Requirements: * * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom( address sender, address recipient, uint256 amount ) public virtual override returns (bool) { _transfer(sender, recipient, amount); uint256 currentAllowance = _allowances[sender][_msgSender()]; require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance"); unchecked { _approve(sender, _msgSender(), currentAllowance - amount); } return true; } /** * @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) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue); return true; } /** * @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) public virtual returns (bool) { uint256 currentAllowance = _allowances[_msgSender()][spender]; require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(_msgSender(), spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `sender` to `recipient`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer( address sender, address recipient, uint256 amount ) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); uint256 senderBalance = _balances[sender]; require(senderBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[sender] = senderBalance - amount; } _balances[recipient] += amount; emit Transfer(sender, recipient, amount); _afterTokenTransfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; _balances[account] += amount; emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; } _totalSupply -= amount; emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} }
import { ISuperfluid, ISuperToken } from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol"; import { IConstantFlowAgreementV1 } from "@superfluid-finance/ethereum-contracts/contracts/interfaces/agreements/IConstantFlowAgreementV1.sol"; import { IInstantDistributionAgreementV1 } from "@superfluid-finance/ethereum-contracts/contracts/interfaces/agreements/IInstantDistributionAgreementV1.sol"; library RicochetLaunchpadStorage { struct RicochetLaunchpad { ISuperfluid host; // Superfluid host contract IConstantFlowAgreementV1 cfa; // The stored constant flow agreement class address IInstantDistributionAgreementV1 ida; // The stored instant dist. agreement class address ISuperToken inputToken; ISuperToken outputToken; address owner; address originator; address beneficiary; uint256 lastDistributionAt; uint256 outputRate; uint32 outputIndexId; uint128 feeRate; uint256 lastSharePrice; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; pragma abicoder v2; import "hardhat/console.sol"; import { ISuperApp, ISuperfluid, ISuperToken, ISuperToken, ISuperAgreement } from "@superfluid-finance/ethereum-contracts/contracts/interfaces/superfluid/ISuperfluid.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "./RicochetLaunchpadStorage.sol"; library RicochetLaunchpadHelper { using SafeERC20 for ERC20; // TODO: Emit these events where appropriate event Distribution(uint256 inputAmount, uint256 outputAmount, uint256 feeCollected); event UpdatedStream(address from, int96 newRate, int96 totalInflow); function _closeStream(RicochetLaunchpadStorage.RicochetLaunchpad storage self, address streamer) public { // Only closable iff their balance is less than 8 hours of streaming (,int96 streamerFlowRate,,) = self.cfa.getFlow(self.inputToken, streamer, address(this)); require(int(self.inputToken.balanceOf(streamer)) <= streamerFlowRate * 8 hours, "!closable"); // Update Subscriptions _updateSubscription(self, self.outputIndexId, streamer, 0, self.outputToken); emit UpdatedStream(streamer, 0, self.cfa.getNetFlow(self.inputToken, address(this))); // Close the streamers stream self.host.callAgreement( self.cfa, abi.encodeWithSelector( self.cfa.deleteFlow.selector, self.inputToken, streamer, address(this), new bytes(0) // placeholder ), "0x" ); } function _emergencyCloseStream(RicochetLaunchpadStorage.RicochetLaunchpad storage self, address streamer) public { // Allows anyone to close any stream iff the app is jailed bool isJailed = self.host.isAppJailed(ISuperApp(address(this))); require(isJailed, "!jailed"); self.host.callAgreement( self.cfa, abi.encodeWithSelector( self.cfa.deleteFlow.selector, self.inputToken, streamer, address(this), new bytes(0) // placeholder ), "0x" ); } function _emergencyDrain(RicochetLaunchpadStorage.RicochetLaunchpad storage self) public { require(self.cfa.getNetFlow(self.inputToken, address(this)) == 0, "!zeroStreamers"); self.inputToken.transfer(self.owner, self.inputToken.balanceOf(address(this))); self.outputToken.transfer(self.owner, self.outputToken.balanceOf(address(this))); } // @dev Distribute a single `amount` of outputToken among all streamers // @dev Calculates the amount to distribute function _distribute( RicochetLaunchpadStorage.RicochetLaunchpad storage self, bytes memory ctx ) external returns (bytes memory newCtx) { newCtx = ctx; require(self.host.isCtxValid(newCtx) || newCtx.length == 0, "!distributeCtx"); // Disperse input tokens to beneficiary and owner uint256 inputAmount = self.inputToken.balanceOf(address(this)); uint256 feeCollected = inputAmount * self.feeRate / 1e6; uint256 distAmount = inputAmount - feeCollected; ISuperToken(self.inputToken).transfer(self.owner, feeCollected); ISuperToken(self.inputToken).transfer(self.beneficiary, distAmount); // Distribute the output tokens to the streamers uint256 outputAmount = (block.timestamp - self.lastDistributionAt) * self.outputRate; if(self.outputToken.balanceOf(address(this)) >= outputAmount) { newCtx = _idaDistribute(self, self.outputIndexId, uint128(outputAmount), self.outputToken, newCtx); self.lastSharePrice = inputAmount * 1e18 / outputAmount; emit Distribution(inputAmount, outputAmount, feeCollected); } self.lastDistributionAt = block.timestamp; return newCtx; } function _idaDistribute(RicochetLaunchpadStorage.RicochetLaunchpad storage self, uint32 index, uint128 distAmount, ISuperToken distToken, bytes memory ctx) internal returns (bytes memory newCtx) { newCtx = ctx; if (newCtx.length == 0) { // No context provided self.host.callAgreement( self.ida, abi.encodeWithSelector( self.ida.distribute.selector, distToken, index, distAmount, new bytes(0) // placeholder ctx ), new bytes(0) // user data ); } else { require(self.host.isCtxValid(newCtx) || newCtx.length == 0, "!distribute"); (newCtx, ) = self.host.callAgreementWithContext( self.ida, abi.encodeWithSelector( self.ida.distribute.selector, distToken, index, distAmount, new bytes(0) // placeholder ctx ), new bytes(0), // user data newCtx ); } } function _createIndex(RicochetLaunchpadStorage.RicochetLaunchpad storage self, uint256 index, ISuperToken distToken) internal { self.host.callAgreement( self.ida, abi.encodeWithSelector( self.ida.createIndex.selector, distToken, index, new bytes(0) // placeholder ctx ), new bytes(0) // user data ); } function _updateSubscription( RicochetLaunchpadStorage.RicochetLaunchpad storage self, uint256 index, address subscriber, uint128 shares, ISuperToken distToken) internal { self.host.callAgreement( self.ida, abi.encodeWithSelector( self.ida.updateSubscription.selector, distToken, index, // one share for the to get it started subscriber, shares / 1e9, new bytes(0) // placeholder ctx ), new bytes(0) // user data ); } function _updateSubscriptionWithContext( RicochetLaunchpadStorage.RicochetLaunchpad storage self, bytes memory ctx, uint256 index, address subscriber, uint128 shares, ISuperToken distToken) internal returns (bytes memory newCtx) { newCtx = ctx; (newCtx, ) = self.host.callAgreementWithContext( self.ida, abi.encodeWithSelector( self.ida.updateSubscription.selector, distToken, index, subscriber, shares / 1e9, // Number of shares is proportional to their rate new bytes(0) ), new bytes(0), // user data newCtx ); } function _deleteSubscriptionWithContext( RicochetLaunchpadStorage.RicochetLaunchpad storage self, bytes memory ctx, address receiver, uint256 index, address subscriber, ISuperToken distToken) internal returns (bytes memory newCtx) { (newCtx, ) = self.host.callAgreementWithContext( self.ida, abi.encodeWithSelector( self.ida.deleteSubscription.selector, distToken, receiver, index, subscriber, new bytes(0) ), new bytes(0), // user data newCtx ); } /************************************************************************** * SuperApp callbacks *************************************************************************/ function _isInputToken(RicochetLaunchpadStorage.RicochetLaunchpad storage self, ISuperToken superToken) internal view returns (bool) { return address(superToken) == address(self.inputToken); } function _isOutputToken(RicochetLaunchpadStorage.RicochetLaunchpad storage self, ISuperToken superToken) internal view returns (bool) { return address(superToken) == address(self.outputToken); } function _isCFAv1(RicochetLaunchpadStorage.RicochetLaunchpad storage self, address agreementClass) internal view returns (bool) { return ISuperAgreement(agreementClass).agreementType() == keccak256("org.superfluid-finance.agreements.ConstantFlowAgreement.v1"); } function _isIDAv1(RicochetLaunchpadStorage.RicochetLaunchpad storage self, address agreementClass) internal view returns (bool) { return ISuperAgreement(agreementClass).agreementType() == keccak256("org.superfluid-finance.agreements.InstantDistributionAgreement.v1"); } }
// SPDX-License-Identifier: AGPLv3 pragma solidity ^0.8.0; interface IREXReferral { function addressToAffiliate (address) view external returns (uint256); /** * @dev Add a market contract to allow-list * @param contractAddr address for REXMarket contract */ function registerApp (address contractAddr) external; /** * @dev Remove a market contract from allow-list * @param contractAddr address for REXMarket contract */ function unregisterApp (address contractAddr) external; /** * @dev Apply for a new affiliate * @param name address for customer * @param affiliateId referral ID */ function applyForAffiliate(string memory name, string memory affiliateId) external; /** * @dev Enable a affiliate and allow to refer customers * @param affiliateId referral ID */ function verifyAffiliate(string memory affiliateId) external; /** * @dev Disable affiliate and disallow to refer customers * @param affiliateId referral ID */ function disableAffiliate(string memory affiliateId) external; /** * @dev Check if an affiliate is enabled * @param affiliateId referral ID */ function isAffiliateEnabled(string memory affiliateId) external view returns (bool); /** * @dev Withdraw affiliate for caller - only allowed for a disabled affiliate */ function withdrawAffiliate() external; /** * @dev Change affiliate address (to transfer rewards) * @param newAddress address for customer */ function changeAffiliateAddress(address newAddress) external; /** * @dev Get affiliate address for customer - returns 0 if customer is organic * @param customerAddr address for customer */ function getAffiliateAddress(address customerAddr) external view returns (address); /** * @dev Perform all checks for customer and register organically or to affiliate when necessary * @param customerAddr address for new customer * @param affiliateId affiliateId of the referral */ function safeRegisterCustomer(address customerAddr, string memory affiliateId) external; }
// 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); }
// 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; }
// 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 }
// 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); }
// 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 ); }
// 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); }
// 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)); } }
// 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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol) pragma solidity ^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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC777Token standard as defined in the EIP. * * This contract uses the * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let * token holders and recipients react to token movements by using setting implementers * for the associated interfaces in said registry. See {IERC1820Registry} and * {ERC1820Implementer}. */ interface IERC777 { /** * @dev 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); }
// 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 {}
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Address.sol) pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT pragma solidity >= 0.4.22 <0.9.0; library console { address constant CONSOLE_ADDRESS = address(0x000000000000000000636F6e736F6c652e6c6f67); function _sendLogPayload(bytes memory payload) private view { uint256 payloadLength = payload.length; address consoleAddress = CONSOLE_ADDRESS; assembly { let payloadStart := add(payload, 32) let r := staticcall(gas(), consoleAddress, payloadStart, payloadLength, 0, 0) } } function log() internal view { _sendLogPayload(abi.encodeWithSignature("log()")); } function logInt(int p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(int)", p0)); } function logUint(uint p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint)", p0)); } function logString(string memory p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); } function logBool(bool p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); } function logAddress(address p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); } function logBytes(bytes memory p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes)", p0)); } function logBytes1(bytes1 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes1)", p0)); } function logBytes2(bytes2 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes2)", p0)); } function logBytes3(bytes3 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes3)", p0)); } function logBytes4(bytes4 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes4)", p0)); } function logBytes5(bytes5 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes5)", p0)); } function logBytes6(bytes6 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes6)", p0)); } function logBytes7(bytes7 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes7)", p0)); } function logBytes8(bytes8 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes8)", p0)); } function logBytes9(bytes9 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes9)", p0)); } function logBytes10(bytes10 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes10)", p0)); } function logBytes11(bytes11 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes11)", p0)); } function logBytes12(bytes12 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes12)", p0)); } function logBytes13(bytes13 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes13)", p0)); } function logBytes14(bytes14 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes14)", p0)); } function logBytes15(bytes15 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes15)", p0)); } function logBytes16(bytes16 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes16)", p0)); } function logBytes17(bytes17 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes17)", p0)); } function logBytes18(bytes18 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes18)", p0)); } function logBytes19(bytes19 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes19)", p0)); } function logBytes20(bytes20 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes20)", p0)); } function logBytes21(bytes21 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes21)", p0)); } function logBytes22(bytes22 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes22)", p0)); } function logBytes23(bytes23 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes23)", p0)); } function logBytes24(bytes24 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes24)", p0)); } function logBytes25(bytes25 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes25)", p0)); } function logBytes26(bytes26 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes26)", p0)); } function logBytes27(bytes27 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes27)", p0)); } function logBytes28(bytes28 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes28)", p0)); } function logBytes29(bytes29 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes29)", p0)); } function logBytes30(bytes30 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes30)", p0)); } function logBytes31(bytes31 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes31)", p0)); } function logBytes32(bytes32 p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bytes32)", p0)); } function log(uint p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint)", p0)); } function log(string memory p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(string)", p0)); } function log(bool p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool)", p0)); } function log(address p0) internal view { _sendLogPayload(abi.encodeWithSignature("log(address)", p0)); } function log(uint p0, uint p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint)", p0, p1)); } function log(uint p0, string memory p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string)", p0, p1)); } function log(uint p0, bool p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool)", p0, p1)); } function log(uint p0, address p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address)", p0, p1)); } function log(string memory p0, uint p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint)", p0, p1)); } function log(string memory p0, string memory p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string)", p0, p1)); } function log(string memory p0, bool p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool)", p0, p1)); } function log(string memory p0, address p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address)", p0, p1)); } function log(bool p0, uint p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint)", p0, p1)); } function log(bool p0, string memory p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string)", p0, p1)); } function log(bool p0, bool p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool)", p0, p1)); } function log(bool p0, address p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address)", p0, p1)); } function log(address p0, uint p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint)", p0, p1)); } function log(address p0, string memory p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string)", p0, p1)); } function log(address p0, bool p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool)", p0, p1)); } function log(address p0, address p1) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address)", p0, p1)); } function log(uint p0, uint p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint)", p0, p1, p2)); } function log(uint p0, uint p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string)", p0, p1, p2)); } function log(uint p0, uint p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool)", p0, p1, p2)); } function log(uint p0, uint p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address)", p0, p1, p2)); } function log(uint p0, string memory p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint)", p0, p1, p2)); } function log(uint p0, string memory p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,string)", p0, p1, p2)); } function log(uint p0, string memory p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool)", p0, p1, p2)); } function log(uint p0, string memory p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,address)", p0, p1, p2)); } function log(uint p0, bool p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint)", p0, p1, p2)); } function log(uint p0, bool p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string)", p0, p1, p2)); } function log(uint p0, bool p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool)", p0, p1, p2)); } function log(uint p0, bool p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address)", p0, p1, p2)); } function log(uint p0, address p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint)", p0, p1, p2)); } function log(uint p0, address p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,string)", p0, p1, p2)); } function log(uint p0, address p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool)", p0, p1, p2)); } function log(uint p0, address p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,address)", p0, p1, p2)); } function log(string memory p0, uint p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint)", p0, p1, p2)); } function log(string memory p0, uint p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,string)", p0, p1, p2)); } function log(string memory p0, uint p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool)", p0, p1, p2)); } function log(string memory p0, uint p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,address)", p0, p1, p2)); } function log(string memory p0, string memory p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint)", p0, p1, p2)); } function log(string memory p0, string memory p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string)", p0, p1, p2)); } function log(string memory p0, string memory p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool)", p0, p1, p2)); } function log(string memory p0, string memory p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address)", p0, p1, p2)); } function log(string memory p0, bool p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint)", p0, p1, p2)); } function log(string memory p0, bool p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string)", p0, p1, p2)); } function log(string memory p0, bool p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool)", p0, p1, p2)); } function log(string memory p0, bool p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address)", p0, p1, p2)); } function log(string memory p0, address p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint)", p0, p1, p2)); } function log(string memory p0, address p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string)", p0, p1, p2)); } function log(string memory p0, address p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool)", p0, p1, p2)); } function log(string memory p0, address p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address)", p0, p1, p2)); } function log(bool p0, uint p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint)", p0, p1, p2)); } function log(bool p0, uint p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string)", p0, p1, p2)); } function log(bool p0, uint p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool)", p0, p1, p2)); } function log(bool p0, uint p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address)", p0, p1, p2)); } function log(bool p0, string memory p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint)", p0, p1, p2)); } function log(bool p0, string memory p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string)", p0, p1, p2)); } function log(bool p0, string memory p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool)", p0, p1, p2)); } function log(bool p0, string memory p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address)", p0, p1, p2)); } function log(bool p0, bool p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint)", p0, p1, p2)); } function log(bool p0, bool p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string)", p0, p1, p2)); } function log(bool p0, bool p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool)", p0, p1, p2)); } function log(bool p0, bool p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address)", p0, p1, p2)); } function log(bool p0, address p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint)", p0, p1, p2)); } function log(bool p0, address p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string)", p0, p1, p2)); } function log(bool p0, address p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool)", p0, p1, p2)); } function log(bool p0, address p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address)", p0, p1, p2)); } function log(address p0, uint p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint)", p0, p1, p2)); } function log(address p0, uint p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,string)", p0, p1, p2)); } function log(address p0, uint p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool)", p0, p1, p2)); } function log(address p0, uint p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,address)", p0, p1, p2)); } function log(address p0, string memory p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint)", p0, p1, p2)); } function log(address p0, string memory p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string)", p0, p1, p2)); } function log(address p0, string memory p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool)", p0, p1, p2)); } function log(address p0, string memory p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address)", p0, p1, p2)); } function log(address p0, bool p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint)", p0, p1, p2)); } function log(address p0, bool p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string)", p0, p1, p2)); } function log(address p0, bool p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool)", p0, p1, p2)); } function log(address p0, bool p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address)", p0, p1, p2)); } function log(address p0, address p1, uint p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint)", p0, p1, p2)); } function log(address p0, address p1, string memory p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string)", p0, p1, p2)); } function log(address p0, address p1, bool p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool)", p0, p1, p2)); } function log(address p0, address p1, address p2) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address)", p0, p1, p2)); } function log(uint p0, uint p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,uint)", p0, p1, p2, p3)); } function log(uint p0, uint p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,string)", p0, p1, p2, p3)); } function log(uint p0, uint p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,bool)", p0, p1, p2, p3)); } function log(uint p0, uint p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,uint,address)", p0, p1, p2, p3)); } function log(uint p0, uint p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,uint)", p0, p1, p2, p3)); } function log(uint p0, uint p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,string)", p0, p1, p2, p3)); } function log(uint p0, uint p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,bool)", p0, p1, p2, p3)); } function log(uint p0, uint p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,string,address)", p0, p1, p2, p3)); } function log(uint p0, uint p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,uint)", p0, p1, p2, p3)); } function log(uint p0, uint p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,string)", p0, p1, p2, p3)); } function log(uint p0, uint p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,bool)", p0, p1, p2, p3)); } function log(uint p0, uint p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,bool,address)", p0, p1, p2, p3)); } function log(uint p0, uint p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,uint)", p0, p1, p2, p3)); } function log(uint p0, uint p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,string)", p0, p1, p2, p3)); } function log(uint p0, uint p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,bool)", p0, p1, p2, p3)); } function log(uint p0, uint p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,uint,address,address)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,uint)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,string)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,bool)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,uint,address)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,uint)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,string)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,bool)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,string,address)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,uint)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,string)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,bool)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,bool,address)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,uint)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,string)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,bool)", p0, p1, p2, p3)); } function log(uint p0, string memory p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,string,address,address)", p0, p1, p2, p3)); } function log(uint p0, bool p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,uint)", p0, p1, p2, p3)); } function log(uint p0, bool p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,string)", p0, p1, p2, p3)); } function log(uint p0, bool p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,bool)", p0, p1, p2, p3)); } function log(uint p0, bool p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,uint,address)", p0, p1, p2, p3)); } function log(uint p0, bool p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,uint)", p0, p1, p2, p3)); } function log(uint p0, bool p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,string)", p0, p1, p2, p3)); } function log(uint p0, bool p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,bool)", p0, p1, p2, p3)); } function log(uint p0, bool p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,string,address)", p0, p1, p2, p3)); } function log(uint p0, bool p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,uint)", p0, p1, p2, p3)); } function log(uint p0, bool p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,string)", p0, p1, p2, p3)); } function log(uint p0, bool p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,bool)", p0, p1, p2, p3)); } function log(uint p0, bool p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,bool,address)", p0, p1, p2, p3)); } function log(uint p0, bool p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,uint)", p0, p1, p2, p3)); } function log(uint p0, bool p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,string)", p0, p1, p2, p3)); } function log(uint p0, bool p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,bool)", p0, p1, p2, p3)); } function log(uint p0, bool p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,bool,address,address)", p0, p1, p2, p3)); } function log(uint p0, address p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,uint)", p0, p1, p2, p3)); } function log(uint p0, address p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,string)", p0, p1, p2, p3)); } function log(uint p0, address p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,bool)", p0, p1, p2, p3)); } function log(uint p0, address p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,uint,address)", p0, p1, p2, p3)); } function log(uint p0, address p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,uint)", p0, p1, p2, p3)); } function log(uint p0, address p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,string)", p0, p1, p2, p3)); } function log(uint p0, address p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,bool)", p0, p1, p2, p3)); } function log(uint p0, address p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,string,address)", p0, p1, p2, p3)); } function log(uint p0, address p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,uint)", p0, p1, p2, p3)); } function log(uint p0, address p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,string)", p0, p1, p2, p3)); } function log(uint p0, address p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,bool)", p0, p1, p2, p3)); } function log(uint p0, address p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,bool,address)", p0, p1, p2, p3)); } function log(uint p0, address p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,uint)", p0, p1, p2, p3)); } function log(uint p0, address p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,string)", p0, p1, p2, p3)); } function log(uint p0, address p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,bool)", p0, p1, p2, p3)); } function log(uint p0, address p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(uint,address,address,address)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,uint)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,string)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,uint,address)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,uint)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,string)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,string,address)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,uint)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,uint)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,string)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, uint p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,uint,address,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,uint)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,uint,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,uint)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,string,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,uint)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,uint)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,string)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, string memory p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,string,address,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,uint)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,uint,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,uint)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,string,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,uint)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,uint)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,string)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, bool p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,bool,address,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,uint)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,uint,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,uint)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,string,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,uint)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,bool,address)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,uint)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,string)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,bool)", p0, p1, p2, p3)); } function log(string memory p0, address p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(string,address,address,address)", p0, p1, p2, p3)); } function log(bool p0, uint p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,uint)", p0, p1, p2, p3)); } function log(bool p0, uint p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,string)", p0, p1, p2, p3)); } function log(bool p0, uint p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,bool)", p0, p1, p2, p3)); } function log(bool p0, uint p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,uint,address)", p0, p1, p2, p3)); } function log(bool p0, uint p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,uint)", p0, p1, p2, p3)); } function log(bool p0, uint p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,string)", p0, p1, p2, p3)); } function log(bool p0, uint p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,bool)", p0, p1, p2, p3)); } function log(bool p0, uint p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,string,address)", p0, p1, p2, p3)); } function log(bool p0, uint p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,uint)", p0, p1, p2, p3)); } function log(bool p0, uint p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,string)", p0, p1, p2, p3)); } function log(bool p0, uint p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, uint p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,bool,address)", p0, p1, p2, p3)); } function log(bool p0, uint p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,uint)", p0, p1, p2, p3)); } function log(bool p0, uint p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,string)", p0, p1, p2, p3)); } function log(bool p0, uint p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,bool)", p0, p1, p2, p3)); } function log(bool p0, uint p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,uint,address,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,uint)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,uint,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,uint)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,string,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,uint)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,bool,address)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,uint)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,string)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,bool)", p0, p1, p2, p3)); } function log(bool p0, string memory p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,string,address,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,uint)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,uint,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,uint)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,string,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,uint)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,bool,address)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,uint)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,string)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,bool)", p0, p1, p2, p3)); } function log(bool p0, bool p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,bool,address,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,uint)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,uint,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,uint)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,string,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,uint)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,bool,address)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,uint)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,string)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,bool)", p0, p1, p2, p3)); } function log(bool p0, address p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(bool,address,address,address)", p0, p1, p2, p3)); } function log(address p0, uint p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,uint)", p0, p1, p2, p3)); } function log(address p0, uint p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,string)", p0, p1, p2, p3)); } function log(address p0, uint p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,bool)", p0, p1, p2, p3)); } function log(address p0, uint p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,uint,address)", p0, p1, p2, p3)); } function log(address p0, uint p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,uint)", p0, p1, p2, p3)); } function log(address p0, uint p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,string)", p0, p1, p2, p3)); } function log(address p0, uint p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,bool)", p0, p1, p2, p3)); } function log(address p0, uint p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,string,address)", p0, p1, p2, p3)); } function log(address p0, uint p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,uint)", p0, p1, p2, p3)); } function log(address p0, uint p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,string)", p0, p1, p2, p3)); } function log(address p0, uint p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,bool)", p0, p1, p2, p3)); } function log(address p0, uint p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,bool,address)", p0, p1, p2, p3)); } function log(address p0, uint p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,uint)", p0, p1, p2, p3)); } function log(address p0, uint p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,string)", p0, p1, p2, p3)); } function log(address p0, uint p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,bool)", p0, p1, p2, p3)); } function log(address p0, uint p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,uint,address,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,uint)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,uint,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,uint)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,string,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,uint)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,bool,address)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,uint)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,string)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,bool)", p0, p1, p2, p3)); } function log(address p0, string memory p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,string,address,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,uint)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,uint,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,uint)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,string,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,uint)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,bool,address)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,uint)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,string)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,bool)", p0, p1, p2, p3)); } function log(address p0, bool p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,bool,address,address)", p0, p1, p2, p3)); } function log(address p0, address p1, uint p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,uint)", p0, p1, p2, p3)); } function log(address p0, address p1, uint p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,string)", p0, p1, p2, p3)); } function log(address p0, address p1, uint p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, uint p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,uint,address)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,uint)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,string)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, string memory p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,string,address)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,uint)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,string)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, bool p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,bool,address)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, uint p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,uint)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, string memory p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,string)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, bool p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,bool)", p0, p1, p2, p3)); } function log(address p0, address p1, address p2, address p3) internal view { _sendLogPayload(abi.encodeWithSignature("log(address,address,address,address)", p0, p1, p2, p3)); } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": { "contracts/launchpad/RicochetLaunchpadHelper.sol": { "RicochetLaunchpadHelper": "0x904b7f03c87833b76d16082bf97922e29d9f407c" } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract ISuperfluid","name":"host","type":"address"},{"internalType":"contract IConstantFlowAgreementV1","name":"cfa","type":"address"},{"internalType":"contract IInstantDistributionAgreementV1","name":"ida","type":"address"},{"internalType":"string","name":"registrationKey","type":"string"},{"internalType":"contract IREXReferral","name":"_rexReferral","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"int96","name":"newRate","type":"int96"},{"indexed":false,"internalType":"int96","name":"totalInflow","type":"int96"}],"name":"UpdatedStream","type":"event"},{"inputs":[{"internalType":"contract ISuperToken","name":"_superToken","type":"address"},{"internalType":"address","name":"_agreementClass","type":"address"},{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"bytes","name":"_agreementData","type":"bytes"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"bytes","name":"_ctx","type":"bytes"}],"name":"afterAgreementCreated","outputs":[{"internalType":"bytes","name":"newCtx","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISuperToken","name":"_superToken","type":"address"},{"internalType":"address","name":"_agreementClass","type":"address"},{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"bytes","name":"_agreementData","type":"bytes"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"bytes","name":"_ctx","type":"bytes"}],"name":"afterAgreementTerminated","outputs":[{"internalType":"bytes","name":"newCtx","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISuperToken","name":"_superToken","type":"address"},{"internalType":"address","name":"_agreementClass","type":"address"},{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"bytes","name":"_agreementData","type":"bytes"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"bytes","name":"_ctx","type":"bytes"}],"name":"afterAgreementUpdated","outputs":[{"internalType":"bytes","name":"newCtx","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISuperToken","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"beforeAgreementCreated","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ISuperToken","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"beforeAgreementTerminated","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ISuperToken","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"beforeAgreementUpdated","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"streamer","type":"address"}],"name":"closeStream","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"distribute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"streamer","type":"address"}],"name":"emergencyCloseStream","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"emergencyDrain","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getFeeRate","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"index","type":"uint32"},{"internalType":"address","name":"streamer","type":"address"}],"name":"getIDAShares","outputs":[{"internalType":"bool","name":"exist","type":"bool"},{"internalType":"bool","name":"approved","type":"bool"},{"internalType":"uint128","name":"units","type":"uint128"},{"internalType":"uint256","name":"pendingDistribution","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getInputToken","outputs":[{"internalType":"contract ISuperToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastDistributionAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOutputIndexId","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOutputRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOutputToken","outputs":[{"internalType":"contract ISuperToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSharePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"streamer","type":"address"}],"name":"getStreamRate","outputs":[{"internalType":"int96","name":"requesterFlowRate","type":"int96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalInflow","outputs":[{"internalType":"int96","name":"","type":"int96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ISuperToken","name":"inputToken","type":"address"},{"internalType":"contract ISuperToken","name":"outputToken","type":"address"},{"internalType":"address","name":"originator","type":"address"},{"internalType":"address","name":"beneficiary","type":"address"},{"internalType":"uint256","name":"outputRate","type":"uint256"},{"internalType":"uint128","name":"feeRate","type":"uint128"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isAppJailed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"feeRate","type":"uint128"}],"name":"setFeeRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b5060405162002c5638038062002c568339810160408190526200003491620003a2565b6200003f33620002de565b6001600160a01b038516620000895760405162461bcd60e51b815260040162000080906020808252600490820152631a1bdcdd60e21b604082015260600190565b60405180910390fd5b6001600160a01b038416620000c75760405162461bcd60e51b815260206004820152600360248201526263666160e81b604482015260640162000080565b6001600160a01b038316620001055760405162461bcd60e51b815260206004820152600360248201526269646160e81b604482015260640162000080565b604051631e51d6a760e11b81523360048201526001600160a01b03861690633ca3ad4e90602401602060405180830381865afa1580156200014a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620001709190620004b0565b15620001aa5760405162461bcd60e51b81526020600482015260086024820152676f776e657220534160c01b604482015260640162000080565b600180546001600160a01b038088166001600160a01b0319928316179092556002805487841690831617905560038054868416908316179055600d80549284169290911691909117905581516415000000019015620002715760015460405163bd1c448b60e01b81526001600160a01b039091169063bd1c448b90620002379084908790600401620004db565b600060405180830381600087803b1580156200025257600080fd5b505af115801562000267573d6000803e3d6000fd5b50505050620002d2565b6001546040516315a722b960e31b8152600481018390526001600160a01b039091169063ad3915c890602401600060405180830381600087803b158015620002b857600080fd5b505af1158015620002cd573d6000803e3d6000fd5b505050505b50505050505062000517565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811681146200034457600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b60005b838110156200037a57818101518382015260200162000360565b838111156200038a576000848401525b50505050565b80516200039d816200032e565b919050565b600080600080600060a08688031215620003bb57600080fd5b8551620003c8816200032e565b6020870151909550620003db816200032e565b6040870151909450620003ee816200032e565b60608701519093506001600160401b03808211156200040c57600080fd5b818801915088601f8301126200042157600080fd5b81518181111562000436576200043662000347565b604051601f8201601f19908116603f0116810190838211818310171562000461576200046162000347565b816040528281528b60208487010111156200047b57600080fd5b6200048e8360208301602088016200035d565b8096505050505050620004a46080870162000390565b90509295509295909350565b600060208284031215620004c357600080fd5b81518015158114620004d457600080fd5b9392505050565b8281526040602082015260008251806040840152620005028160608501602087016200035d565b601f01601f1916919091016060019392505050565b61272f80620005276000396000f3fe608060405234801561001057600080fd5b50600436106101a95760003560e01c8063715018a6116100f9578063b3acf80211610097578063de4b9e9311610071578063de4b9e93146103b8578063e4fc6b6d146103cb578063e52e43da146103d3578063f2fde38b146103e457600080fd5b8063b3acf8021461038a578063cdf5bd751461039d578063d86ed3e5146103a557600080fd5b8063893d20e8116100d3578063893d20e81461034d5780638da5cb5b1461035e578063a3ee6ca01461036f578063a72f8d301461037757600080fd5b8063715018a61461030657806384e5eed01461030e578063884d1f401461033a57600080fd5b806330d9c9151161016657806353c11f991161014057806353c11f99146102bb5780635b1dac60146102ce5780635f9e7d77146102e057806369f07e05146102f357600080fd5b806330d9c91514610275578063416c339d146102885780634fec0ca4146102a357600080fd5b80630c9dfd1e146101ae5780630f2dc3d6146101fb57806315843a011461021057806316305cd814610228578063230dbd291461024d5780632caac08b1461026d575b600080fd5b6101c16101bc366004611bf6565b6103f7565b6040516101f29493929190931515845291151560208401526001600160801b03166040830152606082015260800190565b60405180910390f35b61020e610209366004611c38565b6104a0565b005b610218610516565b60405190151581526020016101f2565b6005546001600160a01b03165b6040516001600160a01b0390911681526020016101f2565b61026061025b366004611ca5565b610588565b6040516101f29190611dc8565b61020e610706565b610260610283366004611ddb565b61076b565b6102906107ce565b604051600b9190910b81526020016101f2565b600b5460405163ffffffff90911681526020016101f2565b6102606102c9366004611ca5565b610849565b600c545b6040519081526020016101f2565b6102606102ee366004611ddb565b61093b565b610290610301366004611c38565b6109a2565b61020e610a2f565b600b5464010000000090046001600160801b03166040516001600160801b0390911681526020016101f2565b610260610348366004611ddb565b610a65565b6006546001600160a01b0316610235565b6000546001600160a01b0316610235565b600a546102d2565b61020e610385366004611e8f565b610ac8565b61020e610398366004611f08565b610ca3565b6009546102d2565b6102606103b3366004611ca5565b610d04565b61020e6103c6366004611c38565b610ecd565b61020e610f14565b6004546001600160a01b0316610235565b61020e6103f2366004611c38565b610fa3565b600354600554600b54604051635b53405160e01b81526001600160a01b03928316600482015230602482015263ffffffff909116604482015283821660648201526000928392839283929190911690635b53405190608401608060405180830381865afa15801561046c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104909190611f3a565b9299919850965090945092505050565b6040516371e390ed60e11b8152600160048201526001600160a01b038216602482015273904b7f03c87833b76d16082bf97922e29d9f407c9063e3c721da906044015b60006040518083038186803b1580156104fb57600080fd5b505af415801561050f573d6000803e3d6000fd5b5050505050565b600154604051636b4f333560e01b81523060048201526000916001600160a01b031690636b4f333590602401602060405180830381865afa15801561055f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105839190611f87565b905090565b60608989610597600182610ff8565b156105f4576004546001600160a01b038084169116146105ef5760405162461bcd60e51b815260206004820152600e60248201526d085a5b9c1d5d1058d8d95c1d195960921b60448201526064015b60405180910390fd5b610653565b6105ff600182611085565b15610653576005546001600160a01b038084169116146106535760405162461bcd60e51b815260206004820152600f60248201526e085bdd5d1c1d5d1058d8d95c1d1959608a1b60448201526064016105e6565b6001546001600160a01b0316331461067d5760405162461bcd60e51b81526004016105e690611fa2565b6004546001600160a01b03808e1691161415806106a257506106a060018c610ff8565b155b156106e65784848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506106f792505050565b6106f485858b8b60016110e6565b92505b50509998505050505050505050565b60405163793a6fd760e01b81526001600482015273904b7f03c87833b76d16082bf97922e29d9f407c9063793a6fd79060240160006040518083038186803b15801561075157600080fd5b505af4158015610765573d6000803e3d6000fd5b50505050565b60405162461bcd60e51b815260206004820152602f60248201527f556e737570706f727465642063616c6c6261636b202d204265666f726520416760448201526e1c99595b595b9d0810dc99585d1959608a1b60648201526060906084016105e6565b6002546004805460405163e8e7e2d160e01b81526001600160a01b0391821692810192909252306024830152600092169063e8e7e2d190604401602060405180830381865afa158015610825573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105839190611fd6565b6001546060906001600160a01b031633146108765760405162461bcd60e51b81526004016105e690611fa2565b6108b46040518060400160405280601881526020017f616674657241677265656d656e745465726d696e6174656400000000000000008152506116ed565b6004546001600160a01b03808c1691161415806108d957506108d760018a610ff8565b155b1561091d5782828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525092935061092e92505050565b61092b8383898960006110e6565b90505b9998505050505050505050565b60405162461bcd60e51b815260206004820152603360248201527f556e737570706f727465642063616c6c6261636b202d20204265666f7265204160448201527219dc99595b595b9d0815195c9b5a5b985d1959606a1b60648201526060906084016105e6565b60025460048054604051631cd43d1160e31b81526001600160a01b03918216928101929092528381166024830152306044830152600092169063e6a1e88890606401608060405180830381865afa158015610a01573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a259190611ff1565b5090949350505050565b6000546001600160a01b03163314610a595760405162461bcd60e51b81526004016105e69061202d565b610a636000611730565b565b60405162461bcd60e51b815260206004820152602f60248201527f556e737570706f727465642063616c6c6261636b202d204265666f726520416760448201526e1c99595b595b9d081d5c19185d1959608a1b60648201526060906084016105e6565b6001600160a01b03861615801590610ae957506004546001600160a01b0316155b610b225760405162461bcd60e51b815260206004820152600a60248201526934b7383aba2a37b5b2b760b11b60448201526064016105e6565b6001600160a01b03851615801590610b4357506005546001600160a01b0316155b610b7d5760405162461bcd60e51b815260206004820152600b60248201526a37baba383aba2a37b5b2b760a91b60448201526064016105e6565b6001600160a01b038416610bc05760405162461bcd60e51b815260206004820152600a60248201526937b934b3b4b730ba37b960b11b60448201526064016105e6565b6001600160a01b038316610c045760405162461bcd60e51b815260206004820152600b60248201526a62656e656669636961727960a81b60448201526064016105e6565b600480546001600160a01b038881166001600160a01b031992831617909255600580548884169083168117909155600b805463ffffffff196001600160801b0387166401000000000216908416179055600a8590556000805460068054851691861691909117905560078054898616908516179055600880549488169490931693909317909155610c9791600191611780565b50504260095550505050565b6000546001600160a01b03163314610ccd5760405162461bcd60e51b81526004016105e69061202d565b600b80546001600160801b039092166401000000000273ffffffffffffffffffffffffffffffff0000000019909216919091179055565b60608989610d13600182610ff8565b15610d6b576004546001600160a01b03808416911614610d665760405162461bcd60e51b815260206004820152600e60248201526d085a5b9c1d5d1058d8d95c1d195960921b60448201526064016105e6565b610dca565b610d76600182611085565b15610dca576005546001600160a01b03808416911614610dca5760405162461bcd60e51b815260206004820152600f60248201526e085bdd5d1c1d5d1058d8d95c1d1959608a1b60448201526064016105e6565b6001546001600160a01b03163314610df45760405162461bcd60e51b81526004016105e690611fa2565b6004546001600160a01b03808e169116141580610e195750610e1760018c610ff8565b155b15610e5d5784848080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509295506106f792505050565b6000610e6b898b018b611c38565b9050610eae86868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525085925061185f915050565b610ebc86868c8c60016110e6565b9d9c50505050505050505050505050565b6040516353081bf960e11b8152600160048201526001600160a01b038216602482015273904b7f03c87833b76d16082bf97922e29d9f407c9063a61037f2906044016104e3565b60408051600081526020810191829052635785ca9b60e01b90915273904b7f03c87833b76d16082bf97922e29d9f407c90635785ca9b90610f5b9060019060248101612078565b600060405180830381865af4158015610f78573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610fa09190810190612157565b50565b6000546001600160a01b03163314610fcd5760405162461bcd60e51b81526004016105e69061202d565b610fd681611a2b565b600680546001600160a01b0319166001600160a01b0392909216919091179055565b60007fa9214cc96615e0085d3bb077758db69497dc2dce3b2b1e97bc93c3d18d83efd3826001600160a01b0316637730599e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611059573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061107d919061218c565b149392505050565b60007f8aedc3b5d4bf031e11a7e2940f7251c005698405d58e02e1c247fed3b1b3a674826001600160a01b0316637730599e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611059573d6000803e3d6000fd5b606085858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250600354600554600b546040516323fc23f360e01b81526001600160a01b03928316600482015230602482015263ffffffff90911660448201529697509195869550911692506323fc23f39150606401608060405180830381865afa158015611186573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111aa91906121a5565b9350935050508380156111cf575060006111c48284612217565b6001600160801b0316115b801561124a5750600480546040516370a0823160e01b815230928101929092526000916001600160a01b03909116906370a0823190602401602060405180830381865afa158015611224573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611248919061218c565b115b156112d157604051635785ca9b60e01b815273904b7f03c87833b76d16082bf97922e29d9f407c90635785ca9b90611289906001908790600401612078565b600060405180830381865af41580156112a6573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526112ce9190810190612157565b92505b6000806112e087890189612242565b90925090506001600160a01b03811630146113285760405162461bcd60e51b815260206004820152600860248201526721617070666c6f7760c01b60448201526064016105e6565b6002546004805460405163e8e7e2d160e01b81526001600160a01b0391821692810192909252306024830152600092169063e8e7e2d190604401602060405180830381865afa15801561137f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113a39190611fd6565b60025460048054604051631cd43d1160e31b81526001600160a01b039182169281019290925286811660248301523060448301529293506000929091169063e6a1e88890606401608060405180830381865afa158015611407573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061142b9190611ff1565b50509150508061708061143e9190612260565b600480546040516370a0823160e01b81526001600160a01b0388811693820193909352600b9390930b929116906370a0823190602401602060405180830381865afa158015611491573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114b5919061218c565b12156114f35760405162461bcd60e51b815260206004820152600d60248201526c21656e6f756768546f6b656e7360981b60448201526064016105e6565b600081600b0b12156115385760405162461bcd60e51b815260206004820152600e60248201526d216e65676174697665526174657360901b60448201526064016105e6565b600d54604051630e9ebfbf60e01b81526001600160a01b0386811660048301526000921690630e9ebfbf90602401602060405180830381865afa158015611583573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a79190612305565b90506001600160a01b0381161561165d5760006115c5606484612338565b6115d0906002612260565b600b54909150611609908a9063ffffffff16846115ee600286612338565b600554600194939291600b0b906001600160a01b0316611ac3565b600b54909950611638908a9063ffffffff1661162d6000546001600160a01b031690565b6115ee600286612338565b600b54909950611655908a9063ffffffff16886115ee858861237b565b985050611690565b600b805460055461168d926001928c9263ffffffff918216928b929089900b916001600160a01b031690611ac316565b97505b604080516001600160a01b0387168152600b84810b602083015285900b8183015290517f757d2a43bda44890ff469605840d40a95d015029fcb64e04fb367a01b87ba9839181900360600190a15050505050505095945050505050565b610fa0816040516024016117019190611dc8565b60408051601f198184030181529190526020810180516001600160e01b031663104c13eb60e21b179052611bc0565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b825460028401546040805160008152602081019091526001600160a01b03928316926339255d5b921690636bc3c20560e11b906117c49086908890604481016123cb565b60408051601f19818403018152918152602080830180516001600160e01b03166001600160e01b03199586161790528151600081529081019182905260e086901b90931690526118189291602481016123fb565b6000604051808303816000875af1158015611837573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526107659190810190612157565b600d5460405163bfdd83f360e01b81526001600160a01b0383811660048301529091169063bfdd83f390602401602060405180830381865afa1580156118a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118cd919061218c565b156119095760405162461bcd60e51b815260206004820152600c60248201526b6e6f416666696c696174657360a01b60448201526064016105e6565b600154604051631fb6491d60e11b81526000916001600160a01b031690633f6c923a9061193a908690600401611dc8565b600060405180830381865afa158015611957573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261197f9190810190612464565b9050606060008260a001515111156119b0578160a001518060200190518101906119a9919061256b565b90506119c1565b506040805160208101909152600081525b600d54604051634a2f43a560e01b81526001600160a01b0390911690634a2f43a5906119f390869085906004016125b4565b600060405180830381600087803b158015611a0d57600080fd5b505af1158015611a21573d6000803e3d6000fd5b5050505050505050565b6000546001600160a01b03163314611a555760405162461bcd60e51b81526004016105e69061202d565b6001600160a01b038116611aba5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016105e6565b610fa081611730565b8554600287015486916001600160a01b0390811691634329d2939116630465a56b60e31b858989611af8633b9aca008b6125d8565b604080516000815260208101909152611b189493929190604481016125fe565b60408051601f19818403018152918152602080830180516001600160e01b03166001600160e01b03199586161790528151600081529081019182905260e086901b9093169052611b6d9291866024820161264b565b6000604051808303816000875af1158015611b8c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611bb49190810190612695565b50979650505050505050565b80516a636f6e736f6c652e6c6f67602083016000808483855afa5050505050565b6001600160a01b0381168114610fa057600080fd5b60008060408385031215611c0957600080fd5b823563ffffffff81168114611c1d57600080fd5b91506020830135611c2d81611be1565b809150509250929050565b600060208284031215611c4a57600080fd5b8135611c5581611be1565b9392505050565b60008083601f840112611c6e57600080fd5b50813567ffffffffffffffff811115611c8657600080fd5b602083019150836020828501011115611c9e57600080fd5b9250929050565b600080600080600080600080600060c08a8c031215611cc357600080fd5b8935611cce81611be1565b985060208a0135611cde81611be1565b975060408a0135965060608a013567ffffffffffffffff80821115611d0257600080fd5b611d0e8d838e01611c5c565b909850965060808c0135915080821115611d2757600080fd5b611d338d838e01611c5c565b909650945060a08c0135915080821115611d4c57600080fd5b50611d598c828d01611c5c565b915080935050809150509295985092959850929598565b60005b83811015611d8b578181015183820152602001611d73565b838111156107655750506000910152565b60008151808452611db4816020860160208601611d70565b601f01601f19169290920160200192915050565b602081526000611c556020830184611d9c565b600080600080600080600060a0888a031215611df657600080fd5b8735611e0181611be1565b96506020880135611e1181611be1565b955060408801359450606088013567ffffffffffffffff80821115611e3557600080fd5b611e418b838c01611c5c565b909650945060808a0135915080821115611e5a57600080fd5b50611e678a828b01611c5c565b989b979a50959850939692959293505050565b6001600160801b0381168114610fa057600080fd5b60008060008060008060c08789031215611ea857600080fd5b8635611eb381611be1565b95506020870135611ec381611be1565b94506040870135611ed381611be1565b93506060870135611ee381611be1565b92506080870135915060a0870135611efa81611e7a565b809150509295509295509295565b600060208284031215611f1a57600080fd5b8135611c5581611e7a565b80518015158114611f3557600080fd5b919050565b60008060008060808587031215611f5057600080fd5b611f5985611f25565b9350611f6760208601611f25565b92506040850151611f7781611e7a565b6060959095015193969295505050565b600060208284031215611f9957600080fd5b611c5582611f25565b6020808252600890820152671bdb99481a1bdcdd60c21b604082015260600190565b8051600b81900b8114611f3557600080fd5b600060208284031215611fe857600080fd5b611c5582611fc4565b6000806000806080858703121561200757600080fd5b8451935061201760208601611fc4565b6040860151606090960151949790965092505050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b634e487b7160e01b600052604160045260246000fd5b8281526040602082015260006120916040830184611d9c565b949350505050565b604051610160810167ffffffffffffffff811182821017156120bd576120bd612062565b60405290565b600067ffffffffffffffff808411156120de576120de612062565b604051601f8501601f19908116603f0116810190828211818310171561210657612106612062565b8160405280935085815286868601111561211f57600080fd5b61212d866020830187611d70565b5050509392505050565b600082601f83011261214857600080fd5b611c55838351602085016120c3565b60006020828403121561216957600080fd5b815167ffffffffffffffff81111561218057600080fd5b61209184828501612137565b60006020828403121561219e57600080fd5b5051919050565b600080600080608085870312156121bb57600080fd5b6121c485611f25565b935060208501516121d481611e7a565b60408601519093506121e581611e7a565b60608601519092506121f681611e7a565b939692955090935050565b634e487b7160e01b600052601160045260246000fd5b60006001600160801b0380831681851680830382111561223957612239612201565b01949350505050565b6000806040838503121561225557600080fd5b8235611c1d81611be1565b600081600b0b83600b0b60016001605f1b0360008213600084138383048511828216161561229057612290612201565b6b7fffffffffffffffffffffff1960008512828116878305871216156122b8576122b8612201565b600087129250858205871284841616156122d4576122d4612201565b858505871281841616156122ea576122ea612201565b5050509290910295945050505050565b8051611f3581611be1565b60006020828403121561231757600080fd5b8151611c5581611be1565b634e487b7160e01b600052601260045260246000fd5b600081600b0b83600b0b8061234f5761234f612322565b6b7fffffffffffffffffffffff1982146000198214161561237257612372612201565b90059392505050565b600081600b0b83600b0b600081128160016001605f1b0319018312811516156123a6576123a6612201565b8160016001605f1b030183138116156123c1576123c1612201565b5090039392505050565b60018060a01b03841681528260208201526060604082015260006123f26060830184611d9c565b95945050505050565b6001600160a01b038416815260606020820181905260009061241f90830185611d9c565b82810360408401526124318185611d9c565b9695505050505050565b805160ff81168114611f3557600080fd5b80516001600160e01b031981168114611f3557600080fd5b60006020828403121561247657600080fd5b815167ffffffffffffffff8082111561248e57600080fd5b9083019061016082860312156124a357600080fd5b6124ab612099565b6124b48361243b565b81526124c26020840161243b565b6020820152604083015160408201526124dd606084016122fa565b60608201526124ee6080840161244c565b608082015260a08301518281111561250557600080fd5b61251187828601612137565b60a08301525060c083015160c082015260e083015160e08201526101009150818301518282015261012091506125488284016122fa565b82820152610140915061255c8284016122fa565b91810191909152949350505050565b60006020828403121561257d57600080fd5b815167ffffffffffffffff81111561259457600080fd5b8201601f810184136125a557600080fd5b612091848251602084016120c3565b6001600160a01b038316815260406020820181905260009061209190830184611d9c565b60006001600160801b03808416806125f2576125f2612322565b92169190910492915050565b6001600160a01b03868116825260208201869052841660408201526001600160801b038316606082015260a06080820181905260009061264090830184611d9c565b979650505050505050565b6001600160a01b038516815260806020820181905260009061266f90830186611d9c565b82810360408401526126818186611d9c565b905082810360608401526126408185611d9c565b600080604083850312156126a857600080fd5b825167ffffffffffffffff808211156126c057600080fd5b6126cc86838701612137565b935060208501519150808211156126e257600080fd5b506126ef85828601612137565b915050925092905056fea2646970667358221220592bd80fb2dac882ba0a3aea1d98c1e4b8ea5cdbfa0884c87012c1bf98c4402564736f6c634300080d00330000000000000000000000003e14dc1b13c488a8d5d310918780c983bd5982e70000000000000000000000006eee6060f715257b970700bc2656de21dedf074c000000000000000000000000b0aabba4b2783a72c52956cdef62d438eca2d7a100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000a0ec9e1542485700110688b3e6fbebbdf23cd90100000000000000000000000000000000000000000000000000000000000000026b31000000000000000000000000000000000000000000000000000000000000
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000003e14dc1b13c488a8d5d310918780c983bd5982e70000000000000000000000006eee6060f715257b970700bc2656de21dedf074c000000000000000000000000b0aabba4b2783a72c52956cdef62d438eca2d7a100000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000a0ec9e1542485700110688b3e6fbebbdf23cd90100000000000000000000000000000000000000000000000000000000000000026b31000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : host (address): 0x3e14dc1b13c488a8d5d310918780c983bd5982e7
Arg [1] : cfa (address): 0x6eee6060f715257b970700bc2656de21dedf074c
Arg [2] : ida (address): 0xb0aabba4b2783a72c52956cdef62d438eca2d7a1
Arg [3] : registrationKey (string): k1
Arg [4] : _rexReferral (address): 0xa0ec9e1542485700110688b3e6fbebbdf23cd901
-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 0000000000000000000000003e14dc1b13c488a8d5d310918780c983bd5982e7
Arg [1] : 0000000000000000000000006eee6060f715257b970700bc2656de21dedf074c
Arg [2] : 000000000000000000000000b0aabba4b2783a72c52956cdef62d438eca2d7a1
Arg [3] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [4] : 000000000000000000000000a0ec9e1542485700110688b3e6fbebbdf23cd901
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [6] : 6b31000000000000000000000000000000000000000000000000000000000000
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.