Contract Overview
My Name Tag:
Not Available, login to update
[ Download CSV Export ]
Contract Name:
StreamExchange
Compiler Version
v0.8.3+commit.8d00100c
Optimization Enabled:
No with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.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 '@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol'; import '@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.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 "./tellor/UsingTellor.sol"; import "./StreamExchangeStorage.sol"; import "./StreamExchangeHelper.sol"; import "./tellor/ITellor.sol"; contract StreamExchange is Ownable, SuperAppBase, UsingTellor { // TODO: uint256 public constant RATE_PERCISION = 1000000; using SafeERC20 for ERC20; using StreamExchangeHelper for StreamExchangeStorage.StreamExchange; using StreamExchangeStorage for StreamExchangeStorage.StreamExchange; StreamExchangeStorage.StreamExchange internal _exchange; event UpdatedStream(address from, int96 newRate, int96 totalInflow); constructor( ISuperfluid host, IConstantFlowAgreementV1 cfa, IInstantDistributionAgreementV1 ida, ISuperToken inputToken, ISuperToken outputToken, ISuperToken subsidyToken, IUniswapV2Router02 sushiRouter, address payable oracle, uint256 requestId, string memory registrationKey) UsingTellor(oracle) { require(address(host) != address(0), "host"); require(address(cfa) != address(0), "cfa"); require(address(ida) != address(0), "ida"); require(address(inputToken) != address(0), "inputToken"); require(address(outputToken) != address(0), "output"); require(!host.isApp(ISuperApp(msg.sender)), "owner SA"); _exchange.sushiRouter = sushiRouter; _exchange.host = host; _exchange.cfa = cfa; _exchange.ida = ida; _exchange.inputToken = inputToken; _exchange.outputToken = outputToken; _exchange.subsidyToken = subsidyToken; _exchange.oracle = ITellor(oracle); _exchange.requestId = requestId; _exchange.feeRate = 20000; _exchange.rateTolerance = 10000; _exchange.subsidyIndexId = 1; _exchange.subsidyRate = 4e17; // 0.4 tokens/second ~ 1,000,000 tokens in a month _exchange.owner = msg.sender; // Unlimited approve for sushiswap ERC20(_exchange.inputToken.getUnderlyingToken()).safeIncreaseAllowance(address(_exchange.sushiRouter), 2**256 - 1); ERC20(_exchange.outputToken.getUnderlyingToken()).safeIncreaseAllowance(address(_exchange.sushiRouter), 2**256 - 1); // and Supertoken upgrades ERC20(_exchange.inputToken.getUnderlyingToken()).safeIncreaseAllowance(address(_exchange.inputToken), 2**256 - 1); ERC20(_exchange.outputToken.getUnderlyingToken()).safeIncreaseAllowance(address(_exchange.outputToken), 2**256 - 1); 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) { _exchange.host.registerAppWithKey(configWord, registrationKey); } else { _exchange.host.registerApp(configWord); } // Set up the IDA for sending tokens back _exchange._createIndex(_exchange.outputIndexId, _exchange.outputToken); // Give the owner 1 share just to start up the contract _exchange._updateSubscription(_exchange.outputIndexId, msg.sender, 1, _exchange.outputToken); // Setup Liquidity Mining _exchange._initalizeLiquidityMining(); _exchange.lastDistributionAt = block.timestamp; } /************************************************************************** * 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) = _exchange.ida.getIndex( _exchange.outputToken, address(this), _exchange.outputIndexId); // Check balance and account for uint256 balance = ISuperToken(_exchange.inputToken).balanceOf(address(this)) / (10 ** (18 - ERC20(_exchange.inputToken.getUnderlyingToken()).decimals())); if (doDistributeFirst && totalUnitsApproved + totalUnitsPending > 0 && balance > 0) { newCtx = _exchange._distribute(newCtx); } (address requester, address flowReceiver) = abi.decode(agreementData, (address, address)); require(flowReceiver == address(this), "!appflow"); int96 appFlowRate = _exchange.cfa.getNetFlow(_exchange.inputToken, address(this)); (, int96 requesterFlowRate, , ) = _exchange.cfa.getFlow(_exchange.inputToken, requester, address(this)); // Make sure the requester has at least 8 hours of balance to stream require(int(_exchange.inputToken.balanceOf(requester)) >= requesterFlowRate * 8 hours, "!enoughTokens"); require(requesterFlowRate >= 0, "!negativeRates"); newCtx = _exchange._updateSubscriptionWithContext(newCtx, _exchange.outputIndexId, requester, uint128(uint(int(requesterFlowRate))), _exchange.outputToken); newCtx = _exchange._updateSubscriptionWithContext(newCtx, _exchange.subsidyIndexId, requester, uint128(uint(int(requesterFlowRate))), _exchange.subsidyToken); emit UpdatedStream(requester, requesterFlowRate, appFlowRate); } function distribute() external { _exchange._distribute(new bytes(0)); } function closeStream(address streamer) public { _exchange._closeStream(streamer); } function emergencyCloseStream(address streamer) public { _exchange._emergencyCloseStream(streamer); } function emergencyDrain() public { _exchange._emergencyDrain(); } function setSubsidyRate(uint128 subsidyRate) external onlyOwner { _exchange.subsidyRate = subsidyRate; } function setFeeRate(uint128 feeRate) external onlyOwner { _exchange.feeRate = feeRate; } function setRateTolerance(uint128 rateTolerance) external onlyOwner { _exchange.rateTolerance = rateTolerance; } function setOracle(address oracle) external onlyOwner { _exchange.oracle = ITellor(oracle); } function setRequestId(uint256 requestId) external onlyOwner { _exchange.requestId = requestId; } function isAppJailed() external view returns (bool) { return _exchange.host.isAppJailed(this); } function getIDAShares(uint32 index, address streamer) external view returns (bool exist, bool approved, uint128 units, uint256 pendingDistribution) { ISuperToken idaToken; if(index == _exchange.outputIndexId) { idaToken = _exchange.outputToken; } else if (index == _exchange.subsidyIndexId) { idaToken = _exchange.subsidyToken; } else { return (exist, approved, units, pendingDistribution); } (exist, approved, units, pendingDistribution) = _exchange.ida.getSubscription( idaToken, address(this), index, streamer); } function getInputToken() external view returns (ISuperToken) { return _exchange.inputToken; } function getOuputToken() external view returns (ISuperToken) { return _exchange.outputToken; } function getOuputIndexId() external view returns (uint32) { return _exchange.outputIndexId; } function getSubsidyToken() external view returns (ISuperToken) { return _exchange.subsidyToken; } function getSubsidyIndexId() external view returns (uint32) { return _exchange.subsidyIndexId; } function getSubsidyRate() external view returns (uint256) { return _exchange.subsidyRate; } function getTotalInflow() external view returns (int96) { return _exchange.cfa.getNetFlow(_exchange.inputToken, address(this)); } function getLastDistributionAt() external view returns (uint256) { return _exchange.lastDistributionAt; } function getSushiRouter() external view returns (address) { return address(_exchange.sushiRouter); } function getTellorOracle() external view returns (address) { return address(_exchange.oracle); } function getRequestId() external view returns (uint256) { return _exchange.requestId; } function getOwner() external view returns (address) { return _exchange.owner; } function getFeeRate() external view returns (uint128) { return _exchange.feeRate; } function getRateTolerance() external view returns (uint256) { return _exchange.rateTolerance; } function getStreamRate(address streamer) external view returns (int96 requesterFlowRate) { (, requesterFlowRate, , ) = _exchange.cfa.getFlow(_exchange.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); _exchange.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) { console.log("afterAgreementCreated"); if (!_exchange._isInputToken(_superToken) || !_exchange._isCFAv1(_agreementClass)) return _ctx; 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) { console.log("afterAgreementUpdated"); console.log(_agreementClass); console.log((address(_superToken))); if (!_exchange._isInputToken(_superToken) || !_exchange._isCFAv1(_agreementClass)) return _ctx; console.log("_updateOutflow"); 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 (!_exchange._isInputToken(_superToken) || !_exchange._isCFAv1(_agreementClass)) return _ctx; // Skip distribution when terminating to avoid reverts return _updateOutflow(_ctx, _agreementData, false); } modifier onlyHost() { require(msg.sender == address(_exchange.host), "one host"); _; } modifier onlyExpected(ISuperToken superToken, address agreementClass) { if (_exchange._isCFAv1(agreementClass)) { require(_exchange._isInputToken(superToken), "!inputAccepted"); } else if (_exchange._isIDAv1(agreementClass)) { require(_exchange._isOutputToken(superToken) || _exchange._isSubsidyToken(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 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); }
// 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"); } }
pragma solidity >=0.5.0; interface IUniswapV2Pair { event Approval(address indexed owner, address indexed spender, uint value); event Transfer(address indexed from, address indexed to, uint value); function name() external pure returns (string memory); function symbol() external pure returns (string memory); function decimals() external pure returns (uint8); function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom(address from, address to, uint value) external returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint); function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; event Mint(address indexed sender, uint amount0, uint amount1); event Burn(address indexed sender, uint amount0, uint amount1, address indexed to); event Swap( address indexed sender, uint amount0In, uint amount1In, uint amount0Out, uint amount1Out, address indexed to ); event Sync(uint112 reserve0, uint112 reserve1); function MINIMUM_LIQUIDITY() external pure returns (uint); function factory() external view returns (address); function token0() external view returns (address); function token1() external view returns (address); function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); function price0CumulativeLast() external view returns (uint); function price1CumulativeLast() external view returns (uint); function kLast() external view returns (uint); function mint(address to) external returns (uint liquidity); function burn(address to) external returns (uint amount0, uint amount1); function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external; function skim(address to) external; function sync() external; function initialize(address, address) external; }
pragma solidity >=0.6.2; import './IUniswapV2Router01.sol'; interface IUniswapV2Router02 is IUniswapV2Router01 { function removeLiquidityETHSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountETH); function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountETH); function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; function swapExactETHForTokensSupportingFeeOnTransferTokens( uint amountOutMin, address[] calldata path, address to, uint deadline ) external payable; function swapExactTokensForETHSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; }
// SPDX-License-Identifier: MIT 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() { _setOwner(_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 { _setOwner(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"); _setOwner(newOwner); } function _setOwner(address newOwner) private { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT 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 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 guidelines: functions revert instead * of 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 {} }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./ITellor.sol"; /** * @title UserContract * This contracts creates for easy integration to the Tellor System * by allowing smart contracts to read data off Tellor */ contract UsingTellor { ITellor private tellor; /*Constructor*/ /** * @dev the constructor sets the storage address and owner * @param _tellor is the TellorMaster address */ constructor(address payable _tellor) { tellor = ITellor(_tellor); } /** * @dev Retreive value from oracle based on requestId/timestamp * @param _requestId being requested * @param _timestamp to retreive data/value from * @return uint value for requestId/timestamp submitted */ function retrieveData(uint256 _requestId, uint256 _timestamp) public view returns (uint256) { return tellor.retrieveData(_requestId, _timestamp); } /** * @dev Gets the 5 miners who mined the value for the specified requestId/_timestamp * @param _requestId to looku p * @param _timestamp is the timestamp to look up miners for * @return bool true if requestId/timestamp is under dispute */ function isInDispute(uint256 _requestId, uint256 _timestamp) public view returns (bool) { return tellor.isInDispute(_requestId, _timestamp); } /** * @dev Counts the number of values that have been submited for the request * @param _requestId the requestId to look up * @return uint count of the number of values received for the requestId */ function getNewValueCountbyRequestId(uint256 _requestId) public view returns (uint256) { return tellor.getNewValueCountbyRequestId(_requestId); } /** * @dev Gets the timestamp for the value based on their index * @param _requestId is the requestId to look up * @param _index is the value index to look up * @return uint timestamp */ function getTimestampbyRequestIDandIndex(uint256 _requestId, uint256 _index) public view returns (uint256) { return tellor.getTimestampbyRequestIDandIndex(_requestId, _index); } /** * @dev Allows the user to get the latest value for the requestId specified * @param _requestId is the requestId to look up the value for * @return ifRetrieve bool true if it is able to retreive a value, the value, and the value's timestamp * @return value the value retrieved * @return _timestampRetrieved the value's timestamp */ function getCurrentValue(uint256 _requestId) public view returns ( bool ifRetrieve, uint256 value, uint256 _timestampRetrieved ) { uint256 _count = tellor.getNewValueCountbyRequestId(_requestId); uint256 _time = tellor.getTimestampbyRequestIDandIndex(_requestId, _count - 1); uint256 _value = tellor.retrieveData(_requestId, _time); if (_value > 0) return (true, _value, _time); return (false, 0, _time); } // slither-disable-next-line calls-loop function getIndexForDataBefore(uint256 _requestId, uint256 _timestamp) public view returns (bool found, uint256 index) { uint256 _count = tellor.getNewValueCountbyRequestId(_requestId); if (_count > 0) { uint256 middle; uint256 start = 0; uint256 end = _count - 1; uint256 _time; //Checking Boundaries to short-circuit the algorithm _time = tellor.getTimestampbyRequestIDandIndex(_requestId, start); if (_time >= _timestamp) return (false, 0); _time = tellor.getTimestampbyRequestIDandIndex(_requestId, end); if (_time < _timestamp) return (true, end); //Since the value is within our boundaries, do a binary search while (true) { middle = (end - start) / 2 + 1 + start; _time = tellor.getTimestampbyRequestIDandIndex( _requestId, middle ); if (_time < _timestamp) { //get imeadiate next value uint256 _nextTime = tellor.getTimestampbyRequestIDandIndex( _requestId, middle + 1 ); if (_nextTime >= _timestamp) { //_time is correct return (true, middle); } else { //look from middle + 1(next value) to end start = middle + 1; } } else { uint256 _prevTime = tellor.getTimestampbyRequestIDandIndex( _requestId, middle - 1 ); if (_prevTime < _timestamp) { // _prevtime is correct return (true, middle - 1); } else { //look from start to middle -1(prev value) end = middle - 1; } } //We couldn't found a value //if(middle - 1 == start || middle == _count) return (false, 0); } } return (false, 0); } /** * @dev Allows the user to get the first value for the requestId before the specified timestamp * @param _requestId is the requestId to look up the value for * @param _timestamp before which to search for first verified value * @return _ifRetrieve bool true if it is able to retreive a value, the value, and the value's timestamp * @return _value the value retrieved * @return _timestampRetrieved the value's timestamp */ function getDataBefore(uint256 _requestId, uint256 _timestamp) public view returns ( bool _ifRetrieve, uint256 _value, uint256 _timestampRetrieved ) { (bool _found, uint256 _index) = getIndexForDataBefore(_requestId, _timestamp); if (!_found) return (false, 0, 0); uint256 _time = tellor.getTimestampbyRequestIDandIndex(_requestId, _index); _value = tellor.retrieveData(_requestId, _time); //If value is diputed it'll return zero if (_value > 0) return (true, _value, _time); return (false, 0, 0); } }
import { ISuperfluid, ISuperToken, ISuperApp, ISuperAgreement, SuperAppDefinitions } 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"; import '@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol'; import "./tellor/ITellor.sol"; library StreamExchangeStorage { struct Stream { int96 rate; } struct StreamExchange { // An exchange generate when StreamExchange is deployed 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; // The input token (e.g. DAIx) ISuperToken outputToken; // The output token (e.g. ETHx) uint32 outputIndexId; ISuperToken subsidyToken; // The token to use as the subsidy uint256 subsidyRate; // The number of tokens to distribute subsidy in units per second uint32 subsidyIndexId; uint256 lastDistributionAt; // The last time a distribution was made IUniswapV2Router02 sushiRouter; // Address of sushsiwap router ITellor oracle; // Address of deployed simple oracle for input//output token uint256 requestId; // The id of the tellor request that has input/output exchange rate uint128 feeRate; // The fee taken as a % with 6 decimals address owner; // The owner of the exchange uint256 rateTolerance; // The percentage to deviate from the oracle scaled to 1e6 } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; pragma abicoder v2; import "hardhat/console.sol"; import { 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 "./tellor/UsingTellor.sol"; import "./StreamExchangeStorage.sol"; library StreamExchangeHelper { using SafeERC20 for ERC20; // TODO: Emit these events where appropriate event Distribution(uint256 totalAmount, uint256 feeCollected, address token); event UpdatedStream(address from, int96 newRate, int96 totalInflow); function _closeStream(StreamExchangeStorage.StreamExchange 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.subsidyIndexId, streamer, 0, self.subsidyToken); _updateSubscription(self, self.outputIndexId, streamer, 0, self.outputToken); // 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" ); emit UpdatedStream(streamer, 0, self.cfa.getNetFlow(self.inputToken, address(this))); } function _emergencyCloseStream(StreamExchangeStorage.StreamExchange storage self, address streamer) public { // Allows anyone to close any stream iff the app is jailed bool isJailed = ISuperfluid(msg.sender).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(StreamExchangeStorage.StreamExchange 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))); } function _getCurrentValue( StreamExchangeStorage.StreamExchange storage self, uint256 _requestId ) public view returns ( bool ifRetrieve, uint256 value, uint256 _timestampRetrieved ) { uint256 _count = self.oracle.getNewValueCountbyRequestId(_requestId); uint256 _time = self.oracle.getTimestampbyRequestIDandIndex(_requestId, _count - 1); uint256 _value = self.oracle.retrieveData(_requestId, _time); if (_value > 0) return (true, _value, _time); return (false, 0, _time); } // @dev Distribute a single `amount` of outputToken among all streamers // @dev Calculates the amount to distribute function _distribute( StreamExchangeStorage.StreamExchange storage self, bytes memory ctx ) external returns (bytes memory newCtx) { newCtx = ctx; require(self.host.isCtxValid(newCtx) || newCtx.length == 0, "!distributeCtx"); uint256 initialBalanceInput = ISuperToken(self.inputToken).balanceOf(address(this)); // Get the exchange rate as inputToken per outputToken bool _didGet; uint _timestamp; uint _value; (_didGet, _value, _timestamp) = _getCurrentValue(self, self.requestId); require(_didGet, "!getCurrentValue"); require(_timestamp >= block.timestamp - 3600, "!currentValue"); _swap(self, ISuperToken(self.inputToken).balanceOf(address(this)), _value, block.timestamp + 3600); uint256 outputBalance = ISuperToken(self.outputToken).balanceOf(address(this)); (uint256 actualAmount,) = self.ida.calculateDistribution( self.outputToken, address(this), self.outputIndexId, outputBalance); // Return if there's not anything to actually distribute if (actualAmount == 0) { return newCtx; } // Calculate the fee for making the distribution uint256 feeCollected = actualAmount * self.feeRate / 1e6; uint256 distAmount = actualAmount - feeCollected; // Calculate subside uint256 subsidyAmount = (block.timestamp - self.lastDistributionAt) * self.subsidyRate; // Confirm the app has enough to distribute require(self.outputToken.balanceOf(address(this)) >= actualAmount, "!enough"); newCtx = _idaDistribute(self, self.outputIndexId, uint128(distAmount), self.outputToken, newCtx); emit Distribution(distAmount, feeCollected, address(self.outputToken)); // Distribute a subsidy if possible if(self.subsidyToken.balanceOf(address(this)) >= subsidyAmount) { newCtx = _idaDistribute(self, self.subsidyIndexId, uint128(subsidyAmount), self.subsidyToken, newCtx); emit Distribution(subsidyAmount, 0, address(self.subsidyToken)); } self.lastDistributionAt = block.timestamp; // Take the fee ISuperToken(self.outputToken).transfer(self.owner, feeCollected); // NOTE: After swapping any token with < 18 decimals, there may be dust left so just leave it require(self.inputToken.balanceOf(address(this)) / 10 ** (18 - ERC20(self.inputToken.getUnderlyingToken()).decimals()) == 0, "!sellAllInput"); return newCtx; } function _swap( StreamExchangeStorage.StreamExchange storage self, uint256 amount, // Assumes this is outputToken.balanceOf(address(this)) uint256 exchangeRate, uint256 deadline ) public returns(uint) { address inputToken; // The underlying input token address address outputToken; // The underlying output token address address[] memory path; // The path to take uint256 minOutput; // The minimum amount of output tokens based on Tellor uint256 outputAmount; // The balance before the swap inputToken = self.inputToken.getUnderlyingToken(); outputToken = self.outputToken.getUnderlyingToken(); // Downgrade and scale the input amount self.inputToken.downgrade(amount); // Scale it to 1e18 for calculations amount = ERC20(inputToken).balanceOf(address(this)) * (10 ** (18 - ERC20(inputToken).decimals())); // TODO: This needs to be "invertable" // USD >> TOK // minOutput = amount * 1e18 / exchangeRate / 1e12; // TOK >> USD minOutput = amount * exchangeRate / 1e6; minOutput = minOutput * (1e6 - self.rateTolerance) / 1e6; // Scale back from 1e18 to outputToken decimals minOutput = minOutput * (10 ** (ERC20(outputToken).decimals())) / 1e18; // Scale it back to inputToken decimals amount = amount / (10 ** (18 - ERC20(inputToken).decimals())); path = new address[](2); path[0] = inputToken; path[1] = outputToken; self.sushiRouter.swapExactTokensForTokens( amount, 0, // Accept any amount but fail if we're too far from the oracle price path, address(this), deadline ); // Assumes `amount` was outputToken.balanceOf(address(this)) outputAmount = ERC20(outputToken).balanceOf(address(this)); require(outputAmount >= minOutput, "BAD_EXCHANGE_RATE: Try again later"); // Convert the outputToken back to its supertoken version self.outputToken.upgrade(outputAmount * (10 ** (18 - ERC20(outputToken).decimals()))); return outputAmount; } function _initalizeLiquidityMining(StreamExchangeStorage.StreamExchange storage self) internal { // Create the index for IDA _createIndex(self, self.subsidyIndexId, self.subsidyToken); // Give the initalizer 1 share to get it started _updateSubscription(self, self.subsidyIndexId, msg.sender, 1, self.subsidyToken); } function _idaDistribute(StreamExchangeStorage.StreamExchange 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(StreamExchangeStorage.StreamExchange 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( StreamExchangeStorage.StreamExchange 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( StreamExchangeStorage.StreamExchange 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( StreamExchangeStorage.StreamExchange 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(StreamExchangeStorage.StreamExchange storage self, ISuperToken superToken) internal view returns (bool) { return address(superToken) == address(self.inputToken); } function _isOutputToken(StreamExchangeStorage.StreamExchange storage self, ISuperToken superToken) internal view returns (bool) { return address(superToken) == address(self.outputToken); } function _isSubsidyToken(StreamExchangeStorage.StreamExchange storage self, ISuperToken superToken) internal view returns (bool) { return address(superToken) == address(self.subsidyToken); } function _isCFAv1(StreamExchangeStorage.StreamExchange storage self, address agreementClass) internal view returns (bool) { return ISuperAgreement(agreementClass).agreementType() == keccak256("org.superfluid-finance.agreements.ConstantFlowAgreement.v1"); } function _isIDAv1(StreamExchangeStorage.StreamExchange storage self, address agreementClass) internal view returns (bool) { return ISuperAgreement(agreementClass).agreementType() == keccak256("org.superfluid-finance.agreements.InstantDistributionAgreement.v1"); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.5.16; interface ITellor { /** * @dev Helps initialize a dispute by assigning it a disputeId * when a miner returns a false on the validate array(in Tellor.ProofOfWork) it sends the * invalidated value information to POS voting * @param _requestId being disputed * @param _timestamp being disputed * @param _minerIndex the index of the miner that submitted the value being disputed. Since each official value * requires 5 miners to submit a value. */ function beginDispute( uint256 _requestId, uint256 _timestamp, uint256 _minerIndex ) external; /** * @dev Allows token holders to vote * @param _disputeId is the dispute id * @param _supportsDispute is the vote (true=the dispute has basis false = vote against dispute) */ function vote(uint256 _disputeId, bool _supportsDispute) external; /** * @dev tallies the votes. * @param _disputeId is the dispute id */ function tallyVotes(uint256 _disputeId) external; /** * @dev Allows for a fork to be proposed * @param _propNewTellorAddress address for new proposed Tellor */ function proposeFork(address _propNewTellorAddress) external; /** * @dev Add tip to Request value from oracle * @param _requestId being requested to be mined * @param _tip amount the requester is willing to pay to be get on queue. Miners * mine the onDeckQueryHash, or the api with the highest payout pool */ function addTip(uint256 _requestId, uint256 _tip) external; /** * @dev This is called by the miner when they submit the PoW solution (proof of work and value) * @param _nonce uint submitted by miner * @param _requestId the apiId being mined * @param _value of api query * */ function submitMiningSolution( string calldata _nonce, uint256 _requestId, uint256 _value ) external; /** * @dev This is called by the miner when they submit the PoW solution (proof of work and value) * @param _nonce uint submitted by miner * @param _requestId is the array of the 5 PSR's being mined * @param _value is an array of 5 values */ function submitMiningSolution( string calldata _nonce, uint256[5] calldata _requestId, uint256[5] calldata _value ) external; /** * @dev Allows the current owner to propose transfer control of the contract to a * newOwner and the ownership is pending until the new owner calls the claimOwnership * function * @param _pendingOwner The address to transfer ownership to. */ function proposeOwnership(address payable _pendingOwner) external; /** * @dev Allows the new owner to claim control of the contract */ function claimOwnership() external; /** * @dev This function allows miners to deposit their stake. */ function depositStake() external; /** * @dev This function allows stakers to request to withdraw their stake (no longer stake) * once they lock for withdraw(stakes.currentStatus = 2) they are locked for 7 days before they * can withdraw the stake */ function requestStakingWithdraw() external; /** * @dev This function allows users to withdraw their stake after a 7 day waiting period from request */ function withdrawStake() external; /** * @dev This function approves a _spender an _amount of tokens to use * @param _spender address * @param _amount amount the spender is being approved for * @return true if spender appproved successfully */ function approve(address _spender, uint256 _amount) external returns (bool); /** * @dev Allows for a transfer of tokens to _to * @param _to The address to send tokens to * @param _amount The amount of tokens to send * @return true if transfer is successful */ function transfer(address _to, uint256 _amount) external returns (bool); /** * @dev Sends _amount tokens to _to from _from on the condition it * is approved by _from * @param _from The address holding the tokens being transferred * @param _to The address of the recipient * @param _amount The amount of tokens to be transferred * @return True if the transfer was successful */ function transferFrom( address _from, address _to, uint256 _amount ) external returns (bool); /** * @dev Allows users to access the token's name */ function name() external pure returns (string memory); /** * @dev Allows users to access the token's symbol */ function symbol() external pure returns (string memory); /** * @dev Allows users to access the number of decimals */ function decimals() external pure returns (uint8); /** * @dev Getter for the current variables that include the 5 requests Id's * @return _challenge _requestIds _difficultky _tip the challenge, 5 requestsId, difficulty and tip */ function getNewCurrentVariables() external view returns ( bytes32 _challenge, uint256[5] memory _requestIds, uint256 _difficutly, uint256 _tip ); /** * @dev Getter for the top tipped 5 requests Id's * @return _requestIds the 5 requestsId */ function getTopRequestIDs() external view returns (uint256[5] memory _requestIds); /** * @dev Getter for the 5 requests Id's next in line to get mined * @return idsOnDeck tipsOnDeck the 5 requestsId */ function getNewVariablesOnDeck() external view returns (uint256[5] memory idsOnDeck, uint256[5] memory tipsOnDeck); /** * @dev Updates the Tellor address after a proposed fork has * passed the vote and day has gone by without a dispute * @param _disputeId the disputeId for the proposed fork */ function updateTellor(uint256 _disputeId) external; /** * @dev Allows disputer to unlock the dispute fee * @param _disputeId to unlock fee from */ function unlockDisputeFee(uint256 _disputeId) external; /** * @param _user address * @param _spender address * @return Returns the remaining allowance of tokens granted to the _spender from the _user */ function allowance(address _user, address _spender) external view returns (uint256); /** * @dev This function returns whether or not a given user is allowed to trade a given amount * @param _user address * @param _amount uint of amount * @return true if the user is alloed to trade the amount specified */ function allowedToTrade(address _user, uint256 _amount) external view returns (bool); /** * @dev Gets balance of owner specified * @param _user is the owner address used to look up the balance * @return Returns the balance associated with the passed in _user */ function balanceOf(address _user) external view returns (uint256); /** * @dev Queries the balance of _user at a specific _blockNumber * @param _user The address from which the balance will be retrieved * @param _blockNumber The block number when the balance is queried * @return The balance at _blockNumber */ function balanceOfAt(address _user, uint256 _blockNumber) external view returns (uint256); /** * @dev This function tells you if a given challenge has been completed by a given miner * @param _challenge the challenge to search for * @param _miner address that you want to know if they solved the challenge * @return true if the _miner address provided solved the */ function didMine(bytes32 _challenge, address _miner) external view returns (bool); /** * @dev Checks if an address voted in a given dispute * @param _disputeId to look up * @param _address to look up * @return bool of whether or not party voted */ function didVote(uint256 _disputeId, address _address) external view returns (bool); /** * @dev allows Tellor to read data from the addressVars mapping * @param _data is the keccak256("variable_name") of the variable that is being accessed. * These are examples of how the variables are saved within other functions: * addressVars[keccak256("_owner")] * addressVars[keccak256("tellorContract")] * return address */ function getAddressVars(bytes32 _data) external view returns (address); /** * @dev Gets all dispute variables * @param _disputeId to look up * @return bytes32 hash of dispute * @return bool executed where true if it has been voted on * @return bool disputeVotePassed * @return bool isPropFork true if the dispute is a proposed fork * @return address of reportedMiner * @return address of reportingParty * @return address of proposedForkAddress * uint of requestId * uint of timestamp * uint of value * uint of minExecutionDate * uint of numberOfVotes * uint of blocknumber * uint of minerSlot * uint of quorum * uint of fee * @return int count of the current tally */ function getAllDisputeVars(uint256 _disputeId) external view returns ( bytes32, bool, bool, bool, address, address, address, uint256[9] memory, int256 ); /** * @dev Getter function for variables for the requestId being currently mined(currentRequestId) * @return current challenge, curretnRequestId, level of difficulty, api/query string, and granularity(number of decimals requested), total tip for the request */ function getCurrentVariables() external view returns ( bytes32, uint256, uint256, string memory, uint256, uint256 ); /** * @dev Checks if a given hash of miner,requestId has been disputed * @param _hash is the sha256(abi.encodePacked(_miners[2],_requestId)); * @return uint disputeId */ function getDisputeIdByDisputeHash(bytes32 _hash) external view returns (uint256); /** * @dev Checks for uint variables in the disputeUintVars mapping based on the disuputeId * @param _disputeId is the dispute id; * @param _data the variable to pull from the mapping. _data = keccak256("variable_name") where variable_name is * the variables/strings used to save the data in the mapping. The variables names are * commented out under the disputeUintVars under the Dispute struct * @return uint value for the bytes32 data submitted */ function getDisputeUintVars(uint256 _disputeId, bytes32 _data) external view returns (uint256); /** * @dev Gets the a value for the latest timestamp available * @return value for timestamp of last proof of work submited * @return true if the is a timestamp for the lastNewValue */ function getLastNewValue() external view returns (uint256, bool); /** * @dev Gets the a value for the latest timestamp available * @param _requestId being requested * @return value for timestamp of last proof of work submited and if true if it exist or 0 and false if it doesn't */ function getLastNewValueById(uint256 _requestId) external view returns (uint256, bool); /** * @dev Gets blocknumber for mined timestamp * @param _requestId to look up * @param _timestamp is the timestamp to look up blocknumber * @return uint of the blocknumber which the dispute was mined */ function getMinedBlockNum(uint256 _requestId, uint256 _timestamp) external view returns (uint256); /** * @dev Gets the 5 miners who mined the value for the specified requestId/_timestamp * @param _requestId to look up * @param _timestamp is the timestamp to look up miners for * @return the 5 miners' addresses */ function getMinersByRequestIdAndTimestamp( uint256 _requestId, uint256 _timestamp ) external view returns (address[5] memory); /** * @dev Counts the number of values that have been submited for the request * if called for the currentRequest being mined it can tell you how many miners have submitted a value for that * request so far * @param _requestId the requestId to look up * @return uint count of the number of values received for the requestId */ function getNewValueCountbyRequestId(uint256 _requestId) external view returns (uint256); /** * @dev Getter function for the specified requestQ index * @param _index to look up in the requestQ array * @return uint of reqeuestId */ function getRequestIdByRequestQIndex(uint256 _index) external view returns (uint256); /** * @dev Getter function for requestId based on timestamp * @param _timestamp to check requestId * @return uint of reqeuestId */ function getRequestIdByTimestamp(uint256 _timestamp) external view returns (uint256); /** * @dev Getter function for requestId based on the queryHash * @param _request is the hash(of string api and granularity) to check if a request already exists * @return uint requestId */ function getRequestIdByQueryHash(bytes32 _request) external view returns (uint256); /** * @dev Getter function for the requestQ array * @return the requestQ arrray */ function getRequestQ() external view returns (uint256[51] memory); /** * @dev Allowes access to the uint variables saved in the apiUintVars under the requestDetails struct * for the requestId specified * @param _requestId to look up * @param _data the variable to pull from the mapping. _data = keccak256("variable_name") where variable_name is * the variables/strings used to save the data in the mapping. The variables names are * commented out under the apiUintVars under the requestDetails struct * @return uint value of the apiUintVars specified in _data for the requestId specified */ function getRequestUintVars(uint256 _requestId, bytes32 _data) external view returns (uint256); /** * @dev Gets the API struct variables that are not mappings * @param _requestId to look up * @return string of api to query * @return string of symbol of api to query * @return bytes32 hash of string * @return bytes32 of the granularity(decimal places) requested * @return uint of index in requestQ array * @return uint of current payout/tip for this requestId */ function getRequestVars(uint256 _requestId) external view returns ( string memory, string memory, bytes32, uint256, uint256, uint256 ); /** * @dev This function allows users to retireve all information about a staker * @param _staker address of staker inquiring about * @return uint current state of staker * @return uint startDate of staking */ function getStakerInfo(address _staker) external view returns (uint256, uint256); /** * @dev Gets the 5 miners who mined the value for the specified requestId/_timestamp * @param _requestId to look up * @param _timestamp is the timestampt to look up miners for * @return address[5] array of 5 addresses ofminers that mined the requestId */ function getSubmissionsByTimestamp(uint256 _requestId, uint256 _timestamp) external view returns (uint256[5] memory); /** * @dev Gets the timestamp for the value based on their index * @param _requestID is the requestId to look up * @param _index is the value index to look up * @return uint timestamp */ function getTimestampbyRequestIDandIndex(uint256 _requestID, uint256 _index) external view returns (uint256); /** * @dev Getter for the variables saved under the TellorStorageStruct uintVars variable * @param _data the variable to pull from the mapping. _data = keccak256("variable_name") where variable_name is * the variables/strings used to save the data in the mapping. The variables names are * commented out under the uintVars under the TellorStorageStruct struct * This is an example of how data is saved into the mapping within other functions: * self.uintVars[keccak256("stakerCount")] * @return uint of specified variable */ function getUintVar(bytes32 _data) external view returns (uint256); /** * @dev Getter function for next requestId on queue/request with highest payout at time the function is called * @return onDeck/info on request with highest payout-- RequestId, Totaltips, and API query string */ function getVariablesOnDeck() external view returns ( uint256, uint256, string memory ); /** * @dev Gets the 5 miners who mined the value for the specified requestId/_timestamp * @param _requestId to look up * @param _timestamp is the timestamp to look up miners for * @return bool true if requestId/timestamp is under dispute */ function isInDispute(uint256 _requestId, uint256 _timestamp) external view returns (bool); /** * @dev Retreive value from oracle based on timestamp * @param _requestId being requested * @param _timestamp to retreive data/value from * @return value for timestamp submitted */ function retrieveData(uint256 _requestId, uint256 _timestamp) external view returns (uint256); /** * @dev Getter for the total_supply of oracle tokens * @return uint total supply */ function totalSupply() external view returns (uint256); }
// 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 updateSuperTokenLogic( ISuperfluid host, ISuperToken token) 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 getAppWhiteListingSecretKey(address deployer, string memory registrationkey) internal pure returns (bytes32) { return keccak256(abi.encode( "org.superfluid-finance.superfluid.appWhiteListing.seed", deployer, registrationkey)); } }
// 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 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 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 {}
pragma solidity >=0.6.2; interface IUniswapV2Router01 { function factory() external pure returns (address); function WETH() external pure returns (address); function addLiquidity( address tokenA, address tokenB, uint amountADesired, uint amountBDesired, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB, uint liquidity); function addLiquidityETH( address token, uint amountTokenDesired, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external payable returns (uint amountToken, uint amountETH, uint liquidity); function removeLiquidity( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB); function removeLiquidityETH( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountToken, uint amountETH); function removeLiquidityWithPermit( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountA, uint amountB); function removeLiquidityETHWithPermit( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountToken, uint amountETH); function swapExactTokensForTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapTokensForExactTokens( uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut); function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn); function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts); function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts); }
// SPDX-License-Identifier: MIT 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 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); } function _verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) private 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 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": false, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "libraries": { "contracts/StreamExchangeHelper.sol": { "StreamExchangeHelper": "0xbb48bd9f99e894e80ab010c3ce029105bbaa9fc6" } } }
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":"contract ISuperToken","name":"inputToken","type":"address"},{"internalType":"contract ISuperToken","name":"outputToken","type":"address"},{"internalType":"contract ISuperToken","name":"subsidyToken","type":"address"},{"internalType":"contract IUniswapV2Router02","name":"sushiRouter","type":"address"},{"internalType":"address payable","name":"oracle","type":"address"},{"internalType":"uint256","name":"requestId","type":"uint256"},{"internalType":"string","name":"registrationKey","type":"string"}],"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":[{"internalType":"uint256","name":"_requestId","type":"uint256"}],"name":"getCurrentValue","outputs":[{"internalType":"bool","name":"ifRetrieve","type":"bool"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"_timestampRetrieved","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_requestId","type":"uint256"},{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"getDataBefore","outputs":[{"internalType":"bool","name":"_ifRetrieve","type":"bool"},{"internalType":"uint256","name":"_value","type":"uint256"},{"internalType":"uint256","name":"_timestampRetrieved","type":"uint256"}],"stateMutability":"view","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":[{"internalType":"uint256","name":"_requestId","type":"uint256"},{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"getIndexForDataBefore","outputs":[{"internalType":"bool","name":"found","type":"bool"},{"internalType":"uint256","name":"index","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":[{"internalType":"uint256","name":"_requestId","type":"uint256"}],"name":"getNewValueCountbyRequestId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOuputIndexId","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOuputToken","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":"getRateTolerance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRequestId","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":"getSubsidyIndexId","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSubsidyRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSubsidyToken","outputs":[{"internalType":"contract ISuperToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSushiRouter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTellorOracle","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_requestId","type":"uint256"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getTimestampbyRequestIDandIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalInflow","outputs":[{"internalType":"int96","name":"","type":"int96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isAppJailed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_requestId","type":"uint256"},{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"isInDispute","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":"uint256","name":"_requestId","type":"uint256"},{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"retrieveData","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint128","name":"feeRate","type":"uint128"}],"name":"setFeeRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"oracle","type":"address"}],"name":"setOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"rateTolerance","type":"uint128"}],"name":"setRateTolerance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"requestId","type":"uint256"}],"name":"setRequestId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"subsidyRate","type":"uint128"}],"name":"setSubsidyRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b50604051620085103803806200851083398181016040528101906200003791906200199e565b82620000586200004c62000d5560201b60201c565b62000d5d60201b60201c565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050600073ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff1614156200010d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620001049062001f80565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168973ffffffffffffffffffffffffffffffffffffffff16141562000180576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620001779062001ef8565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168873ffffffffffffffffffffffffffffffffffffffff161415620001f3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620001ea9062002008565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff16141562000266576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200025d9062001f1a565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168673ffffffffffffffffffffffffffffffffffffffff161415620002d9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620002d09062001fc4565b60405180910390fd5b8973ffffffffffffffffffffffffffffffffffffffff16633ca3ad4e336040518263ffffffff1660e01b815260040162000314919062001e0f565b60206040518083038186803b1580156200032d57600080fd5b505afa15801562000342573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200036891906200192d565b15620003ab576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620003a29062001fa2565b60405180910390fd5b83600260090160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555089600260000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555088600260010160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550876002800160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555086600260030160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555085600260040160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555084600260050160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550826002600a0160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550816002600b0181905550614e206002600c0160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff1602179055506127106002600e01819055506001600260070160006101000a81548163ffffffff021916908363ffffffff16021790555067058d15e176280000600260060181905550336002600d0160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550620007b6600260090160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600260030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ee719bc86040518163ffffffff1660e01b815260040160206040518083038186803b1580156200075057600080fd5b505afa15801562000765573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906200078b919062001901565b73ffffffffffffffffffffffffffffffffffffffff1662000e2160201b6200285c179092919060201c565b620008d3600260090160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600260040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ee719bc86040518163ffffffff1660e01b815260040160206040518083038186803b1580156200086d57600080fd5b505afa15801562000882573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620008a8919062001901565b73ffffffffffffffffffffffffffffffffffffffff1662000e2160201b6200285c179092919060201c565b620009f0600260030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600260030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ee719bc86040518163ffffffff1660e01b815260040160206040518083038186803b1580156200098a57600080fd5b505afa1580156200099f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620009c5919062001901565b73ffffffffffffffffffffffffffffffffffffffff1662000e2160201b6200285c179092919060201c565b62000b0d600260040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600260040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ee719bc86040518163ffffffff1660e01b815260040160206040518083038186803b15801562000aa757600080fd5b505afa15801562000abc573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000ae2919062001901565b73ffffffffffffffffffffffffffffffffffffffff1662000e2160201b6200285c179092919060201c565b60006410000000006404000000006401000000006001171717905060008251111562000bcf57600260000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663bd1c448b82846040518363ffffffff1660e01b815260040162000b9592919062002047565b600060405180830381600087803b15801562000bb057600080fd5b505af115801562000bc5573d6000803e3d6000fd5b5050505062000c64565b600260000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ad3915c8826040518263ffffffff1660e01b815260040162000c2f91906200202a565b600060405180830381600087803b15801562000c4a57600080fd5b505af115801562000c5f573d6000803e3d6000fd5b505050505b62000cc1600260040160149054906101000a900463ffffffff1663ffffffff16600260040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600262000f5460201b6200297d179092919060201c565b62000d23600260040160149054906101000a900463ffffffff1663ffffffff16336001600260040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166002620011a160201b62002bbe1790949392919060201c565b62000d3a60026200140560201b62002e141760201c565b426002600801819055505050505050505050505050620026ef565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000818473ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e30866040518363ffffffff1660e01b815260040162000e6192919062001d6a565b60206040518083038186803b15801562000e7a57600080fd5b505afa15801562000e8f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062000eb5919062001aa7565b62000ec1919062002153565b905062000f4e8463095ea7b360e01b858460405160240162000ee592919062001d97565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050620014ad60201b60201c565b50505050565b8260000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166339255d5b8460020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1663d787840a60e01b8486600067ffffffffffffffff81111562001005577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015620010385781602001600182028036833780820191505090505b506040516024016200104d9392919062001e90565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050600067ffffffffffffffff811115620010ec577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156200111f5781602001600182028036833780820191505090505b506040518463ffffffff1660e01b8152600401620011409392919062001dc4565b600060405180830381600087803b1580156200115b57600080fd5b505af115801562001170573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906200119b919062001959565b50505050565b8460000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166339255d5b8660020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1663232d2b5860e01b848888633b9aca0089620012239190620021b0565b600067ffffffffffffffff81111562001265577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015620012985781602001600182028036833780820191505090505b50604051602401620012af95949392919062001e2c565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050600067ffffffffffffffff8111156200134e577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015620013815781602001600182028036833780820191505090505b506040518463ffffffff1660e01b8152600401620013a29392919062001dc4565b600060405180830381600087803b158015620013bd57600080fd5b505af1158015620013d2573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190620013fd919062001959565b505050505050565b62001456818260070160009054906101000a900463ffffffff1663ffffffff168360050160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1662000f5460201b60201c565b620014aa818260070160009054906101000a900463ffffffff1663ffffffff163360018560050160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16620011a160201b60201c565b50565b600062001516826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166200158160201b62002eac179092919060201c565b90506000815111156200157c57808060200190518101906200153991906200192d565b6200157b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620015729062001fe6565b60405180910390fd5b5b505050565b6060620015988484600085620015a160201b60201c565b90509392505050565b606082471015620015e9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620015e09062001f3c565b60405180910390fd5b620015fa85620016cf60201b60201c565b6200163c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620016339062001f5e565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405162001667919062001d51565b60006040518083038185875af1925050503d8060008114620016a6576040519150601f19603f3d011682016040523d82523d6000602084013e620016ab565b606091505b5091509150620016c3828286620016e260201b60201c565b92505050949350505050565b600080823b905060008111915050919050565b60608315620016f45782905062001747565b600083511115620017085782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200173e919062001ed4565b60405180910390fd5b9392505050565b6000620017656200175f84620020a4565b6200207b565b9050828152602081018484840111156200177e57600080fd5b6200178b8482856200233e565b509392505050565b6000620017aa620017a484620020da565b6200207b565b905082815260208101848484011115620017c357600080fd5b620017d08482856200233e565b509392505050565b600081519050620017e98162002605565b92915050565b60008151905062001800816200261f565b92915050565b600081519050620018178162002639565b92915050565b600082601f8301126200182f57600080fd5b8151620018418482602086016200174e565b91505092915050565b6000815190506200185b8162002653565b92915050565b60008151905062001872816200266d565b92915050565b600081519050620018898162002687565b92915050565b600081519050620018a081620026a1565b92915050565b600081519050620018b781620026bb565b92915050565b600082601f830112620018cf57600080fd5b8151620018e184826020860162001793565b91505092915050565b600081519050620018fb81620026d5565b92915050565b6000602082840312156200191457600080fd5b60006200192484828501620017d8565b91505092915050565b6000602082840312156200194057600080fd5b6000620019508482850162001806565b91505092915050565b6000602082840312156200196c57600080fd5b600082015167ffffffffffffffff8111156200198757600080fd5b62001995848285016200181d565b91505092915050565b6000806000806000806000806000806101408b8d031215620019bf57600080fd5b6000620019cf8d828e016200188f565b9a50506020620019e28d828e016200184a565b9950506040620019f58d828e0162001861565b985050606062001a088d828e0162001878565b975050608062001a1b8d828e0162001878565b96505060a062001a2e8d828e0162001878565b95505060c062001a418d828e01620018a6565b94505060e062001a548d828e01620017ef565b93505061010062001a688d828e01620018ea565b9250506101208b015167ffffffffffffffff81111562001a8757600080fd5b62001a958d828e01620018bd565b9150509295989b9194979a5092959850565b60006020828403121562001aba57600080fd5b600062001aca84828501620018ea565b91505092915050565b62001ade81620021e8565b82525050565b600062001af18262002110565b62001afd818562002126565b935062001b0f8185602086016200233e565b62001b1a8162002437565b840191505092915050565b600062001b328262002110565b62001b3e818562002137565b935062001b508185602086016200233e565b80840191505092915050565b62001b6781620022c6565b82525050565b62001b7881620022ee565b82525050565b62001b898162002316565b82525050565b600062001b9c826200211b565b62001ba8818562002142565b935062001bba8185602086016200233e565b62001bc58162002437565b840191505092915050565b600062001bdf60038362002142565b915062001bec8262002448565b602082019050919050565b600062001c06600a8362002142565b915062001c138262002471565b602082019050919050565b600062001c2d60268362002142565b915062001c3a826200249a565b604082019050919050565b600062001c54601d8362002142565b915062001c6182620024e9565b602082019050919050565b600062001c7b60048362002142565b915062001c888262002512565b602082019050919050565b600062001ca260088362002142565b915062001caf826200253b565b602082019050919050565b600062001cc960068362002142565b915062001cd68262002564565b602082019050919050565b600062001cf0602a8362002142565b915062001cfd826200258d565b604082019050919050565b600062001d1760038362002142565b915062001d2482620025dc565b602082019050919050565b62001d3a8162002280565b82525050565b62001d4b81620022bc565b82525050565b600062001d5f828462001b25565b915081905092915050565b600060408201905062001d81600083018562001ad3565b62001d90602083018462001ad3565b9392505050565b600060408201905062001dae600083018562001ad3565b62001dbd602083018462001d40565b9392505050565b600060608201905062001ddb600083018662001b5c565b818103602083015262001def818562001ae4565b9050818103604083015262001e05818462001ae4565b9050949350505050565b600060208201905062001e26600083018462001b6d565b92915050565b600060a08201905062001e43600083018862001b7e565b62001e52602083018762001d40565b62001e61604083018662001ad3565b62001e70606083018562001d2f565b818103608083015262001e84818462001ae4565b90509695505050505050565b600060608201905062001ea7600083018662001b7e565b62001eb6602083018562001d40565b818103604083015262001eca818462001ae4565b9050949350505050565b6000602082019050818103600083015262001ef0818462001b8f565b905092915050565b6000602082019050818103600083015262001f138162001bd0565b9050919050565b6000602082019050818103600083015262001f358162001bf7565b9050919050565b6000602082019050818103600083015262001f578162001c1e565b9050919050565b6000602082019050818103600083015262001f798162001c45565b9050919050565b6000602082019050818103600083015262001f9b8162001c6c565b9050919050565b6000602082019050818103600083015262001fbd8162001c93565b9050919050565b6000602082019050818103600083015262001fdf8162001cba565b9050919050565b60006020820190508181036000830152620020018162001ce1565b9050919050565b60006020820190508181036000830152620020238162001d08565b9050919050565b600060208201905062002041600083018462001d40565b92915050565b60006040820190506200205e600083018562001d40565b818103602083015262002072818462001b8f565b90509392505050565b6000620020876200209a565b905062002095828262002374565b919050565b6000604051905090565b600067ffffffffffffffff821115620020c257620020c162002408565b5b620020cd8262002437565b9050602081019050919050565b600067ffffffffffffffff821115620020f857620020f762002408565b5b620021038262002437565b9050602081019050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b60006200216082620022bc565b91506200216d83620022bc565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115620021a557620021a4620023aa565b5b828201905092915050565b6000620021bd8262002280565b9150620021ca8362002280565b925082620021dd57620021dc620023d9565b5b828204905092915050565b6000620021f5826200229c565b9050919050565b600062002209826200229c565b9050919050565b60008115159050919050565b60006200222982620021e8565b9050919050565b60006200223d82620021e8565b9050919050565b60006200225182620021e8565b9050919050565b60006200226582620021e8565b9050919050565b60006200227982620021e8565b9050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b6000620022d382620022da565b9050919050565b6000620022e7826200229c565b9050919050565b6000620022fb8262002302565b9050919050565b60006200230f826200229c565b9050919050565b600062002323826200232a565b9050919050565b600062002337826200229c565b9050919050565b60005b838110156200235e57808201518184015260208101905062002341565b838111156200236e576000848401525b50505050565b6200237f8262002437565b810181811067ffffffffffffffff82111715620023a157620023a062002408565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f6366610000000000000000000000000000000000000000000000000000000000600082015250565b7f696e707574546f6b656e00000000000000000000000000000000000000000000600082015250565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b7f686f737400000000000000000000000000000000000000000000000000000000600082015250565b7f6f776e6572205341000000000000000000000000000000000000000000000000600082015250565b7f6f75747075740000000000000000000000000000000000000000000000000000600082015250565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b7f6964610000000000000000000000000000000000000000000000000000000000600082015250565b6200261081620021e8565b81146200261c57600080fd5b50565b6200262a81620021fc565b81146200263657600080fd5b50565b620026448162002210565b81146200265057600080fd5b50565b6200265e816200221c565b81146200266a57600080fd5b50565b620026788162002230565b81146200268457600080fd5b50565b620026928162002244565b81146200269e57600080fd5b50565b620026ac8162002258565b8114620026b857600080fd5b50565b620026c6816200226c565b8114620026d257600080fd5b50565b620026e081620022bc565b8114620026ec57600080fd5b50565b615e1180620026ff6000396000f3fe608060405234801561001057600080fd5b506004361061025e5760003560e01c80637adbf97311610146578063a75d6daa116100c3578063cdf5bd7511610087578063cdf5bd751461076b578063d86ed3e514610789578063de4b9e93146107b9578063e4fc6b6d146107d5578063e52e43da146107df578063f2fde38b146107fd5761025e565b8063a75d6daa146106c6578063ad2ffd9c146106e4578063b3acf80214610700578063b73e49791461071c578063c277c3761461074d5761025e565b80638d21b5931161010a5780638d21b5931461061e5780638da5cb5b1461063c578063903891871461065a57806393fa4915146106785780639c42a999146106a85761025e565b80637adbf9731461057857806380f8620f1461059457806384e5eed0146105b2578063884d1f40146105d0578063893d20e8146106005761025e565b80633fcad964116101df5780635f9e7d77116101a35780635f9e7d771461048e57806366b44611146104be57806369f07e05146104f0578063715018a61461052057806372667cdb1461052a57806377fbb663146105485761025e565b80633fcad964146103c2578063416c339d146103f457806346eee1c4146104125780634933e08c1461044257806353c11f991461045e5761025e565b8063246497ed11610226578063246497ed1461031e57806329fe587b1461033a5780632caac08b1461035857806330d9c915146103625780633df0777b146103925761025e565b8063077001b9146102635780630c9dfd1e146102815780630f2dc3d6146102b457806315843a01146102d0578063230dbd29146102ee575b600080fd5b61026b610819565b60405161027891906152cd565b60405180910390f35b61029b60048036038101906102969190614893565b610826565b6040516102ab9493929190614d31565b60405180910390f35b6102ce60048036038101906102c9919061436e565b6109af565b005b6102d8610a1e565b6040516102e59190614d16565b60405180910390f35b61030860048036038101906103039190614671565b610ad3565b6040516103159190614dd6565b60405180910390f35b61033860048036038101906103339190614779565b610d94565b005b610342610e2f565b60405161034f91906152cd565b60405180910390f35b610360610e3c565b005b61037c600480360381019061037791906145c1565b610ea8565b6040516103899190614dd6565b60405180910390f35b6103ac60048036038101906103a79190614857565b610ee5565b6040516103b99190614d16565b60405180910390f35b6103dc60048036038101906103d791906147a2565b610f9c565b6040516103eb93929190614d9f565b60405180910390f35b6103fc6111ed565b6040516104099190615041565b60405180910390f35b61042c600480360381019061042791906147a2565b6112c9565b60405161043991906152cd565b60405180910390f35b61045c600480360381019061045791906147a2565b61137d565b005b61047860048036038101906104739190614671565b611406565b6040516104859190614dd6565b60405180910390f35b6104a860048036038101906104a391906145c1565b611579565b6040516104b59190614dd6565b60405180910390f35b6104d860048036038101906104d39190614857565b6115b6565b6040516104e793929190614d9f565b60405180910390f35b61050a6004803603810190610505919061436e565b611774565b6040516105179190615041565b60405180910390f35b61052861185d565b005b6105326118e5565b60405161053f9190614c72565b60405180910390f35b610562600480360381019061055d9190614857565b611912565b60405161056f91906152cd565b60405180910390f35b610592600480360381019061058d919061436e565b6119c9565b005b61059c611a8c565b6040516105a99190614c72565b60405180910390f35b6105ba611ab9565b6040516105c791906152b2565b60405180910390f35b6105ea60048036038101906105e591906145c1565b611ae2565b6040516105f79190614dd6565b60405180910390f35b610608611b1f565b6040516106159190614c72565b60405180910390f35b610626611b4c565b60405161063391906152cd565b60405180910390f35b610644611b59565b6040516106519190614c72565b60405180910390f35b610662611b82565b60405161066f9190615311565b60405180910390f35b610692600480360381019061068d9190614857565b611b9f565b60405161069f91906152cd565b60405180910390f35b6106b0611c56565b6040516106bd9190614e97565b60405180910390f35b6106ce611c83565b6040516106db9190615311565b60405180910390f35b6106fe60048036038101906106f99190614779565b611ca0565b005b61071a60048036038101906107159190614779565b611d3b565b005b61073660048036038101906107319190614857565b611df6565b604051610744929190614d76565b60405180910390f35b610755612342565b6040516107629190614e97565b60405180910390f35b61077361236f565b60405161078091906152cd565b60405180910390f35b6107a3600480360381019061079e9190614671565b61237c565b6040516107b09190614dd6565b60405180910390f35b6107d360048036038101906107ce919061436e565b6125ed565b005b6107dd61265c565b005b6107e7612763565b6040516107f49190614e97565b60405180910390f35b6108176004803603810190610812919061436e565b612790565b005b60006002600b0154905090565b6000806000806000600260040160149054906101000a900463ffffffff1663ffffffff168763ffffffff16141561088457600260040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506108e1565b600260070160009054906101000a900463ffffffff1663ffffffff168763ffffffff1614156108da57600260050160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506108e0565b506109a6565b5b6002800160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635b53405182308a8a6040518563ffffffff1660e01b81526004016109449493929190614f49565b60806040518083038186803b15801561095c57600080fd5b505afa158015610970573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109949190614425565b80955081965082975083985050505050505b92959194509250565b600273bb48bd9f99e894e80ab010c3ce029105bbaa9fc6636ffbff6c9091836040518363ffffffff1660e01b81526004016109eb929190615259565b60006040518083038186803b158015610a0357600080fd5b505af4158015610a17573d6000803e3d6000fd5b5050505050565b6000600260000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636b4f3335306040518263ffffffff1660e01b8152600401610a7e9190615026565b60206040518083038186803b158015610a9657600080fd5b505afa158015610aaa573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ace91906143fc565b905090565b60608989610aeb816002612ec490919063ffffffff16565b15610b4857610b04826002612f6e90919063ffffffff16565b610b43576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b3a906151de565b60405180910390fd5b610bd1565b610b5c816002612fcb90919063ffffffff16565b15610bd057610b7582600261307590919063ffffffff16565b80610b905750610b8f8260026130d290919063ffffffff16565b5b610bcf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bc69061515e565b60405180910390fd5b5b5b600260000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610c64576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c5b906150de565b60405180910390fd5b610ca26040518060400160405280601581526020017f616674657241677265656d656e7455706461746564000000000000000000000081525061312f565b610cab8b6131c8565b610cb48c6131c8565b610cc88c6002612f6e90919063ffffffff16565b1580610ce55750610ce38b6002612ec490919063ffffffff16565b155b15610d365784848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509250610d85565b610d746040518060400160405280600e81526020017f5f7570646174654f7574666c6f7700000000000000000000000000000000000081525061312f565b610d8285858b8b6001613261565b92505b50509998505050505050505050565b610d9c613af0565b73ffffffffffffffffffffffffffffffffffffffff16610dba611b59565b73ffffffffffffffffffffffffffffffffffffffff1614610e10576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e079061513e565b60405180910390fd5b806fffffffffffffffffffffffffffffffff166002600e018190555050565b6000600260060154905090565b600273bb48bd9f99e894e80ab010c3ce029105bbaa9fc663884086b890916040518263ffffffff1660e01b8152600401610e76919061523e565b60006040518083038186803b158015610e8e57600080fd5b505af4158015610ea2573d6000803e3d6000fd5b50505050565b60606040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610edc906151fe565b60405180910390fd5b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16633df0777b84846040518363ffffffff1660e01b8152600401610f449291906152e8565b60206040518083038186803b158015610f5c57600080fd5b505afa158015610f70573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f9491906143fc565b905092915050565b600080600080600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166346eee1c4866040518263ffffffff1660e01b8152600401610ffd91906152cd565b60206040518083038186803b15801561101557600080fd5b505afa158015611029573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061104d91906147cb565b90506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166377fbb6638760018561109d9190615734565b6040518363ffffffff1660e01b81526004016110ba9291906152e8565b60206040518083038186803b1580156110d257600080fd5b505afa1580156110e6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061110a91906147cb565b90506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166393fa491588846040518363ffffffff1660e01b815260040161116b9291906152e8565b60206040518083038186803b15801561118357600080fd5b505afa158015611197573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111bb91906147cb565b905060008111156111d857600181839550955095505050506111e6565b600080839550955095505050505b9193909250565b6000600260010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e8e7e2d1600260030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16306040518363ffffffff1660e01b8152600401611274929190614eb2565b60206040518083038186803b15801561128c57600080fd5b505afa1580156112a0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112c49190614750565b905090565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166346eee1c4836040518263ffffffff1660e01b815260040161132691906152cd565b60206040518083038186803b15801561133e57600080fd5b505afa158015611352573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061137691906147cb565b9050919050565b611385613af0565b73ffffffffffffffffffffffffffffffffffffffff166113a3611b59565b73ffffffffffffffffffffffffffffffffffffffff16146113f9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113f09061513e565b60405180910390fd5b806002600b018190555050565b6060600260000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461149b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611492906150de565b60405180910390fd5b6114d96040518060400160405280601881526020017f616674657241677265656d656e745465726d696e61746564000000000000000081525061312f565b6114ed8a6002612f6e90919063ffffffff16565b158061150a5750611508896002612ec490919063ffffffff16565b155b1561155b5782828080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050905061156c565b611569838389896000613261565b90505b9998505050505050505050565b60606040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115ad906150fe565b60405180910390fd5b60008060008060006115c88787611df6565b91509150816115e3576000806000945094509450505061176d565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166377fbb66389846040518363ffffffff1660e01b81526004016116429291906152e8565b60206040518083038186803b15801561165a57600080fd5b505afa15801561166e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061169291906147cb565b9050600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166393fa491589836040518363ffffffff1660e01b81526004016116f19291906152e8565b60206040518083038186803b15801561170957600080fd5b505afa15801561171d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061174191906147cb565b9450600085111561175e576001858295509550955050505061176d565b60008060009550955095505050505b9250925092565b6000600260010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e6a1e888600260030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1684306040518463ffffffff1660e01b81526004016117fd93929190614edb565b60806040518083038186803b15801561181557600080fd5b505afa158015611829573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061184d91906147f4565b9091925090505080915050919050565b611865613af0565b73ffffffffffffffffffffffffffffffffffffffff16611883611b59565b73ffffffffffffffffffffffffffffffffffffffff16146118d9576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016118d09061513e565b60405180910390fd5b6118e36000613af8565b565b6000600260090160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166377fbb66384846040518363ffffffff1660e01b81526004016119719291906152e8565b60206040518083038186803b15801561198957600080fd5b505afa15801561199d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119c191906147cb565b905092915050565b6119d1613af0565b73ffffffffffffffffffffffffffffffffffffffff166119ef611b59565b73ffffffffffffffffffffffffffffffffffffffff1614611a45576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a3c9061513e565b60405180910390fd5b806002600a0160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60006002600a0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60006002600c0160009054906101000a90046fffffffffffffffffffffffffffffffff16905090565b60606040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b169061517e565b60405180910390fd5b60006002600d0160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60006002600e0154905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600260040160149054906101000a900463ffffffff16905090565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166393fa491584846040518363ffffffff1660e01b8152600401611bfe9291906152e8565b60206040518083038186803b158015611c1657600080fd5b505afa158015611c2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c4e91906147cb565b905092915050565b6000600260040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600260070160009054906101000a900463ffffffff16905090565b611ca8613af0565b73ffffffffffffffffffffffffffffffffffffffff16611cc6611b59565b73ffffffffffffffffffffffffffffffffffffffff1614611d1c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d139061513e565b60405180910390fd5b806fffffffffffffffffffffffffffffffff1660026006018190555050565b611d43613af0565b73ffffffffffffffffffffffffffffffffffffffff16611d61611b59565b73ffffffffffffffffffffffffffffffffffffffff1614611db7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611dae9061513e565b60405180910390fd5b806002600c0160006101000a8154816fffffffffffffffffffffffffffffffff02191690836fffffffffffffffffffffffffffffffff16021790555050565b6000806000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166346eee1c4866040518263ffffffff1660e01b8152600401611e5691906152cd565b60206040518083038186803b158015611e6e57600080fd5b505afa158015611e82573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ea691906147cb565b9050600081111561233257600080600090506000600184611ec79190615734565b90506000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166377fbb6638a856040518363ffffffff1660e01b8152600401611f289291906152e8565b60206040518083038186803b158015611f4057600080fd5b505afa158015611f54573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f7891906147cb565b9050878110611f925760008096509650505050505061233b565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166377fbb6638a846040518363ffffffff1660e01b8152600401611fef9291906152e8565b60206040518083038186803b15801561200757600080fd5b505afa15801561201b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061203f91906147cb565b90508781101561205a5760018296509650505050505061233b565b5b60011561232d57826001600285856120739190615734565b61207d91906154a3565b612087919061541c565b612091919061541c565b9350600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166377fbb6638a866040518363ffffffff1660e01b81526004016120f09291906152e8565b60206040518083038186803b15801561210857600080fd5b505afa15801561211c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061214091906147cb565b905087811015612235576000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166377fbb6638b600188612198919061541c565b6040518363ffffffff1660e01b81526004016121b59291906152e8565b60206040518083038186803b1580156121cd57600080fd5b505afa1580156121e1573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061220591906147cb565b9050888110612220576001859750975050505050505061233b565b60018561222d919061541c565b935050612328565b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166377fbb6638b6001886122839190615734565b6040518363ffffffff1660e01b81526004016122a09291906152e8565b60206040518083038186803b1580156122b857600080fd5b505afa1580156122cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122f091906147cb565b90508881101561231757600180866123089190615734565b9750975050505050505061233b565b6001856123249190615734565b9250505b61205b565b505050505b60008092509250505b9250929050565b6000600260050160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000600260080154905090565b60608989612394816002612ec490919063ffffffff16565b156123f1576123ad826002612f6e90919063ffffffff16565b6123ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123e3906151de565b60405180910390fd5b61247a565b612405816002612fcb90919063ffffffff16565b156124795761241e82600261307590919063ffffffff16565b8061243957506124388260026130d290919063ffffffff16565b5b612478576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161246f9061515e565b60405180910390fd5b5b5b600260000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff161461250d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612504906150de565b60405180910390fd5b61254b6040518060400160405280601581526020017f616674657241677265656d656e7443726561746564000000000000000000000081525061312f565b61255f8c6002612f6e90919063ffffffff16565b158061257c575061257a8b6002612ec490919063ffffffff16565b155b156125cd5784848080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505092506125de565b6125db85858b8b6001613261565b92505b50509998505050505050505050565b600273bb48bd9f99e894e80ab010c3ce029105bbaa9fc66332627eda9091836040518363ffffffff1660e01b8152600401612629929190615259565b60006040518083038186803b15801561264157600080fd5b505af4158015612655573d6000803e3d6000fd5b5050505050565b600273bb48bd9f99e894e80ab010c3ce029105bbaa9fc6637575b1c99091600067ffffffffffffffff8111156126bb577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156126ed5781602001600182028036833780820191505090505b506040518363ffffffff1660e01b815260040161270b929190615282565b60006040518083038186803b15801561272357600080fd5b505af4158015612737573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f820116820180604052508101906127609190614514565b50565b6000600260030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b612798613af0565b73ffffffffffffffffffffffffffffffffffffffff166127b6611b59565b73ffffffffffffffffffffffffffffffffffffffff161461280c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128039061513e565b60405180910390fd5b61281581613bbc565b806002600d0160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b6000818473ffffffffffffffffffffffffffffffffffffffff1663dd62ed3e30866040518363ffffffff1660e01b815260040161289a929190614c8d565b60206040518083038186803b1580156128b257600080fd5b505afa1580156128c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906128ea91906147cb565b6128f4919061541c565b90506129778463095ea7b360e01b8584604051602401612915929190614ced565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613cb4565b50505050565b8260000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166339255d5b8460020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1663d787840a60e01b8486600067ffffffffffffffff811115612a2d577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015612a5f5781602001600182028036833780820191505090505b50604051602401612a7293929190614fe8565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050600067ffffffffffffffff811115612b10577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015612b425781602001600182028036833780820191505090505b506040518463ffffffff1660e01b8152600401612b6193929190614df8565b600060405180830381600087803b158015612b7b57600080fd5b505af1158015612b8f573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190612bb89190614514565b50505050565b8460000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166339255d5b8660020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1663232d2b5860e01b848888633b9aca0089612c3e9190615472565b600067ffffffffffffffff811115612c7f577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015612cb15781602001600182028036833780820191505090505b50604051602401612cc6959493929190614f8e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050600067ffffffffffffffff811115612d64577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015612d965781602001600182028036833780820191505090505b506040518463ffffffff1660e01b8152600401612db593929190614df8565b600060405180830381600087803b158015612dcf57600080fd5b505af1158015612de3573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f82011682018060405250810190612e0c9190614514565b505050505050565b612e5d818260070160009054906101000a900463ffffffff1663ffffffff168360050160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1661297d565b612ea9818260070160009054906101000a900463ffffffff1663ffffffff163360018560050160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16612bbe565b50565b6060612ebb8484600085613d7b565b90509392505050565b60007fa9214cc96615e0085d3bb077758db69497dc2dce3b2b1e97bc93c3d18d83efd38273ffffffffffffffffffffffffffffffffffffffff16637730599e6040518163ffffffff1660e01b815260040160206040518083038186803b158015612f2d57600080fd5b505afa158015612f41573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f6591906144eb565b14905092915050565b60008260030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614905092915050565b60007f8aedc3b5d4bf031e11a7e2940f7251c005698405d58e02e1c247fed3b1b3a6748273ffffffffffffffffffffffffffffffffffffffff16637730599e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561303457600080fd5b505afa158015613048573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061306c91906144eb565b14905092915050565b60008260040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614905092915050565b60008260050160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614905092915050565b6131c581604051602401613143919061505c565b6040516020818303038152906040527f41304fac000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613e8f565b50565b61325e816040516024016131dc9190614c72565b6040516020818303038152906040527f2c2ecbc2000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050613e8f565b50565b606085858080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505090506000806002800160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166323fc23f3600260040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1630600260040160149054906101000a900463ffffffff166040518463ffffffff1660e01b815260040161334893929190614f12565b60806040518083038186803b15801561336057600080fd5b505afa158015613374573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133989190614488565b9350935050506000600260030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ee719bc86040518163ffffffff1660e01b815260040160206040518083038186803b15801561340b57600080fd5b505afa15801561341f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134439190614397565b73ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561348857600080fd5b505afa15801561349c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134c091906148cf565b60126134cc9190615768565b600a6134d89190615527565b600260030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016135369190614c72565b60206040518083038186803b15801561354e57600080fd5b505afa158015613562573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061358691906147cb565b61359091906154a3565b90508480156135bc5750600082846135a891906153d6565b6fffffffffffffffffffffffffffffffff16115b80156135c85750600081115b1561366157600273bb48bd9f99e894e80ab010c3ce029105bbaa9fc6637575b1c99091866040518363ffffffff1660e01b8152600401613609929190615282565b60006040518083038186803b15801561362157600080fd5b505af4158015613635573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061365e9190614514565b93505b600080888881019061367391906143c0565b915091503073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146136e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136dc906151be565b60405180910390fd5b6000600260010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e8e7e2d1600260030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16306040518363ffffffff1660e01b815260040161376c929190614eb2565b60206040518083038186803b15801561378457600080fd5b505afa158015613798573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137bc9190614750565b90506000600260010160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663e6a1e888600260030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1686306040518463ffffffff1660e01b815260040161384793929190614edb565b60806040518083038186803b15801561385f57600080fd5b505afa158015613873573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061389791906147f4565b5050915050617080816138aa9190615645565b600b0b600260030160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166370a08231866040518263ffffffff1660e01b815260040161390b9190614c72565b60206040518083038186803b15801561392357600080fd5b505afa158015613937573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061395b91906147cb565b121561399c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016139939061507e565b60405180910390fd5b600081600b0b12156139e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016139da9061509e565b60405180910390fd5b613a4288600260040160149054906101000a900463ffffffff1663ffffffff168684600b0b600260040160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166002613eb89095949392919063ffffffff16565b9750613aa388600260070160009054906101000a900463ffffffff1663ffffffff168684600b0b600260050160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff166002613eb89095949392919063ffffffff16565b97507f757d2a43bda44890ff469605840d40a95d015029fcb64e04fb367a01b87ba983848284604051613ad893929190614cb6565b60405180910390a15050505050505095945050505050565b600033905090565b60008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050816000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b613bc4613af0565b73ffffffffffffffffffffffffffffffffffffffff16613be2611b59565b73ffffffffffffffffffffffffffffffffffffffff1614613c38576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613c2f9061513e565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415613ca8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613c9f906150be565b60405180910390fd5b613cb181613af8565b50565b6000613d16826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612eac9092919063ffffffff16565b9050600081511115613d765780806020019051810190613d3691906143fc565b613d75576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613d6c9061521e565b60405180910390fd5b5b505050565b606082471015613dc0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613db79061511e565b60405180910390fd5b613dc98561411c565b613e08576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613dff9061519e565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff168587604051613e319190614c5b565b60006040518083038185875af1925050503d8060008114613e6e576040519150601f19603f3d011682016040523d82523d6000602084013e613e73565b606091505b5091509150613e8382828661412f565b92505050949350505050565b60008151905060006a636f6e736f6c652e6c6f679050602083016000808483855afa5050505050565b60608590508660000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16634329d2938860020160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1663232d2b5860e01b858989633b9aca008a613f3d9190615472565b600067ffffffffffffffff811115613f7e577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015613fb05781602001600182028036833780820191505090505b50604051602401613fc5959493929190614f8e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050600067ffffffffffffffff811115614063577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156140955781602001600182028036833780820191505090505b50856040518563ffffffff1660e01b81526004016140b69493929190614e3d565b600060405180830381600087803b1580156140d057600080fd5b505af11580156140e4573d6000803e3d6000fd5b505050506040513d6000823e3d601f19601f8201168201806040525081019061410d9190614555565b50809150509695505050505050565b600080823b905060008111915050919050565b6060831561413f5782905061418f565b6000835111156141525782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401614186919061505c565b60405180910390fd5b9392505050565b60006141a96141a484615351565b61532c565b9050828152602081018484840111156141c157600080fd5b6141cc8482856158c4565b509392505050565b6000813590506141e381615cf5565b92915050565b6000815190506141f881615cf5565b92915050565b60008135905061420d81615d0c565b92915050565b60008151905061422281615d23565b92915050565b60008135905061423781615d3a565b92915050565b60008151905061424c81615d3a565b92915050565b60008083601f84011261426457600080fd5b8235905067ffffffffffffffff81111561427d57600080fd5b60208301915083600182028301111561429557600080fd5b9250929050565b600082601f8301126142ad57600080fd5b81516142bd848260208601614196565b91505092915050565b6000813590506142d581615d51565b92915050565b6000815190506142ea81615d68565b92915050565b6000813590506142ff81615d7f565b92915050565b60008151905061431481615d7f565b92915050565b60008135905061432981615d96565b92915050565b60008151905061433e81615d96565b92915050565b60008135905061435381615dad565b92915050565b60008151905061436881615dc4565b92915050565b60006020828403121561438057600080fd5b600061438e848285016141d4565b91505092915050565b6000602082840312156143a957600080fd5b60006143b7848285016141e9565b91505092915050565b600080604083850312156143d357600080fd5b60006143e1858286016141fe565b92505060206143f2858286016141fe565b9150509250929050565b60006020828403121561440e57600080fd5b600061441c84828501614213565b91505092915050565b6000806000806080858703121561443b57600080fd5b600061444987828801614213565b945050602061445a87828801614213565b935050604061446b87828801614305565b925050606061447c8782880161432f565b91505092959194509250565b6000806000806080858703121561449e57600080fd5b60006144ac87828801614213565b94505060206144bd87828801614305565b93505060406144ce87828801614305565b92505060606144df87828801614305565b91505092959194509250565b6000602082840312156144fd57600080fd5b600061450b8482850161423d565b91505092915050565b60006020828403121561452657600080fd5b600082015167ffffffffffffffff81111561454057600080fd5b61454c8482850161429c565b91505092915050565b6000806040838503121561456857600080fd5b600083015167ffffffffffffffff81111561458257600080fd5b61458e8582860161429c565b925050602083015167ffffffffffffffff8111156145ab57600080fd5b6145b78582860161429c565b9150509250929050565b600080600080600080600060a0888a0312156145dc57600080fd5b60006145ea8a828b016142c6565b97505060206145fb8a828b016141d4565b965050604061460c8a828b01614228565b955050606088013567ffffffffffffffff81111561462957600080fd5b6146358a828b01614252565b9450945050608088013567ffffffffffffffff81111561465457600080fd5b6146608a828b01614252565b925092505092959891949750929550565b600080600080600080600080600060c08a8c03121561468f57600080fd5b600061469d8c828d016142c6565b99505060206146ae8c828d016141d4565b98505060406146bf8c828d01614228565b97505060608a013567ffffffffffffffff8111156146dc57600080fd5b6146e88c828d01614252565b965096505060808a013567ffffffffffffffff81111561470757600080fd5b6147138c828d01614252565b945094505060a08a013567ffffffffffffffff81111561473257600080fd5b61473e8c828d01614252565b92509250509295985092959850929598565b60006020828403121561476257600080fd5b6000614770848285016142db565b91505092915050565b60006020828403121561478b57600080fd5b6000614799848285016142f0565b91505092915050565b6000602082840312156147b457600080fd5b60006147c28482850161431a565b91505092915050565b6000602082840312156147dd57600080fd5b60006147eb8482850161432f565b91505092915050565b6000806000806080858703121561480a57600080fd5b60006148188782880161432f565b9450506020614829878288016142db565b935050604061483a8782880161432f565b925050606061484b8782880161432f565b91505092959194509250565b6000806040838503121561486a57600080fd5b60006148788582860161431a565b92505060206148898582860161431a565b9150509250929050565b600080604083850312156148a657600080fd5b60006148b485828601614344565b92505060206148c5858286016141d4565b9150509250929050565b6000602082840312156148e157600080fd5b60006148ef84828501614359565b91505092915050565b6149018161579c565b82525050565b6149108161579c565b82525050565b61491f816157c0565b82525050565b600061493082615382565b61493a8185615398565b935061494a8185602086016158c4565b614953816159b5565b840191505092915050565b600061496982615382565b61497381856153a9565b93506149838185602086016158c4565b61498c816159b5565b840191505092915050565b60006149a282615382565b6149ac81856153ba565b93506149bc8185602086016158c4565b80840191505092915050565b6149d181615858565b82525050565b6149e08161587c565b82525050565b6149ef816158a0565b82525050565b6149fe816157e8565b82525050565b6000614a0f8261538d565b614a1981856153c5565b9350614a298185602086016158c4565b614a32816159b5565b840191505092915050565b6000614a4a600d836153c5565b9150614a55826159d3565b602082019050919050565b6000614a6d600e836153c5565b9150614a78826159fc565b602082019050919050565b6000614a906026836153c5565b9150614a9b82615a25565b604082019050919050565b6000614ab36008836153c5565b9150614abe82615a74565b602082019050919050565b6000614ad66033836153c5565b9150614ae182615a9d565b604082019050919050565b6000614af96026836153c5565b9150614b0482615aec565b604082019050919050565b6000614b1c6020836153c5565b9150614b2782615b3b565b602082019050919050565b6000614b3f600f836153c5565b9150614b4a82615b64565b602082019050919050565b6000614b62602f836153c5565b9150614b6d82615b8d565b604082019050919050565b6000614b85601d836153c5565b9150614b9082615bdc565b602082019050919050565b6000614ba86008836153c5565b9150614bb382615c05565b602082019050919050565b6000614bcb600e836153c5565b9150614bd682615c2e565b602082019050919050565b6000614bee602f836153c5565b9150614bf982615c57565b604082019050919050565b6000614c11602a836153c5565b9150614c1c82615ca6565b604082019050919050565b8082525050565b614c37816157f5565b82525050565b614c4681615831565b82525050565b614c558161583b565b82525050565b6000614c678284614997565b915081905092915050565b6000602082019050614c8760008301846148f8565b92915050565b6000604082019050614ca260008301856148f8565b614caf60208301846148f8565b9392505050565b6000606082019050614ccb60008301866148f8565b614cd860208301856149f5565b614ce560408301846149f5565b949350505050565b6000604082019050614d0260008301856148f8565b614d0f6020830184614c3d565b9392505050565b6000602082019050614d2b6000830184614916565b92915050565b6000608082019050614d466000830187614916565b614d536020830186614916565b614d606040830185614c2e565b614d6d6060830184614c3d565b95945050505050565b6000604082019050614d8b6000830185614916565b614d986020830184614c3d565b9392505050565b6000606082019050614db46000830186614916565b614dc16020830185614c3d565b614dce6040830184614c3d565b949350505050565b60006020820190508181036000830152614df08184614925565b905092915050565b6000606082019050614e0d60008301866149c8565b8181036020830152614e1f8185614925565b90508181036040830152614e338184614925565b9050949350505050565b6000608082019050614e5260008301876149c8565b8181036020830152614e648186614925565b90508181036040830152614e788185614925565b90508181036060830152614e8c8184614925565b905095945050505050565b6000602082019050614eac60008301846149d7565b92915050565b6000604082019050614ec760008301856149d7565b614ed460208301846148f8565b9392505050565b6000606082019050614ef060008301866149d7565b614efd60208301856148f8565b614f0a60408301846148f8565b949350505050565b6000606082019050614f2760008301866149d7565b614f3460208301856148f8565b614f416040830184614c4c565b949350505050565b6000608082019050614f5e60008301876149d7565b614f6b60208301866148f8565b614f786040830185614c4c565b614f8560608301846148f8565b95945050505050565b600060a082019050614fa360008301886149d7565b614fb06020830187614c3d565b614fbd60408301866148f8565b614fca6060830185614c2e565b8181036080830152614fdc8184614925565b90509695505050505050565b6000606082019050614ffd60008301866149d7565b61500a6020830185614c3d565b818103604083015261501c8184614925565b9050949350505050565b600060208201905061503b60008301846149e6565b92915050565b600060208201905061505660008301846149f5565b92915050565b600060208201905081810360008301526150768184614a04565b905092915050565b6000602082019050818103600083015261509781614a3d565b9050919050565b600060208201905081810360008301526150b781614a60565b9050919050565b600060208201905081810360008301526150d781614a83565b9050919050565b600060208201905081810360008301526150f781614aa6565b9050919050565b6000602082019050818103600083015261511781614ac9565b9050919050565b6000602082019050818103600083015261513781614aec565b9050919050565b6000602082019050818103600083015261515781614b0f565b9050919050565b6000602082019050818103600083015261517781614b32565b9050919050565b6000602082019050818103600083015261519781614b55565b9050919050565b600060208201905081810360008301526151b781614b78565b9050919050565b600060208201905081810360008301526151d781614b9b565b9050919050565b600060208201905081810360008301526151f781614bbe565b9050919050565b6000602082019050818103600083015261521781614be1565b9050919050565b6000602082019050818103600083015261523781614c04565b9050919050565b60006020820190506152536000830184614c27565b92915050565b600060408201905061526e6000830185614c27565b61527b6020830184614907565b9392505050565b60006040820190506152976000830185614c27565b81810360208301526152a9818461495e565b90509392505050565b60006020820190506152c76000830184614c2e565b92915050565b60006020820190506152e26000830184614c3d565b92915050565b60006040820190506152fd6000830185614c3d565b61530a6020830184614c3d565b9392505050565b60006020820190506153266000830184614c4c565b92915050565b6000615336615347565b905061534282826158f7565b919050565b6000604051905090565b600067ffffffffffffffff82111561536c5761536b615986565b5b615375826159b5565b9050602081019050919050565b600081519050919050565b600081519050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b60006153e1826157f5565b91506153ec836157f5565b9250826fffffffffffffffffffffffffffffffff0382111561541157615410615928565b5b828201905092915050565b600061542782615831565b915061543283615831565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561546757615466615928565b5b828201905092915050565b600061547d826157f5565b9150615488836157f5565b92508261549857615497615957565b5b828204905092915050565b60006154ae82615831565b91506154b983615831565b9250826154c9576154c8615957565b5b828204905092915050565b6000808291508390505b600185111561551e578086048111156154fa576154f9615928565b5b60018516156155095780820291505b8081029050615517856159c6565b94506154de565b94509492505050565b600061553282615831565b915061553d8361584b565b925061556a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8484615572565b905092915050565b600082615582576001905061563e565b81615590576000905061563e565b81600181146155a657600281146155b0576155df565b600191505061563e565b60ff8411156155c2576155c1615928565b5b8360020a9150848211156155d9576155d8615928565b5b5061563e565b5060208310610133831016604e8410600b84101617156156145782820a90508381111561560f5761560e615928565b5b61563e565b61562184848460016154d4565b9250905081840481111561563857615637615928565b5b81810290505b9392505050565b6000615650826157e8565b915061565b836157e8565b9250826b7fffffffffffffffffffffff048211600084136000841316161561568657615685615928565b5b817fffffffffffffffffffffffffffffffffffffffff80000000000000000000000005831260008412600084131616156156c3576156c2615928565b5b827fffffffffffffffffffffffffffffffffffffffff8000000000000000000000000582126000841360008412161615615700576156ff615928565b5b826b7fffffffffffffffffffffff058212600084126000841216161561572957615728615928565b5b828202905092915050565b600061573f82615831565b915061574a83615831565b92508282101561575d5761575c615928565b5b828203905092915050565b60006157738261584b565b915061577e8361584b565b92508282101561579157615790615928565b5b828203905092915050565b60006157a782615811565b9050919050565b60006157b982615811565b9050919050565b60008115159050919050565b6000819050919050565b60006157e18261579c565b9050919050565b600081600b0b9050919050565b60006fffffffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600063ffffffff82169050919050565b600060ff82169050919050565b60006158638261586a565b9050919050565b600061587582615811565b9050919050565b60006158878261588e565b9050919050565b600061589982615811565b9050919050565b60006158ab826158b2565b9050919050565b60006158bd82615811565b9050919050565b60005b838110156158e25780820151818401526020810190506158c7565b838111156158f1576000848401525b50505050565b615900826159b5565b810181811067ffffffffffffffff8211171561591f5761591e615986565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b60008160011c9050919050565b7f21656e6f756768546f6b656e7300000000000000000000000000000000000000600082015250565b7f216e656761746976655261746573000000000000000000000000000000000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f6f6e6520686f7374000000000000000000000000000000000000000000000000600082015250565b7f556e737570706f727465642063616c6c6261636b202d20204265666f7265204160008201527f677265656d656e74205465726d696e6174656400000000000000000000000000602082015250565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f216f757470757441636365707465640000000000000000000000000000000000600082015250565b7f556e737570706f727465642063616c6c6261636b202d204265666f726520416760008201527f7265656d656e7420757064617465640000000000000000000000000000000000602082015250565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b7f21617070666c6f77000000000000000000000000000000000000000000000000600082015250565b7f21696e7075744163636570746564000000000000000000000000000000000000600082015250565b7f556e737570706f727465642063616c6c6261636b202d204265666f726520416760008201527f7265656d656e7420437265617465640000000000000000000000000000000000602082015250565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b615cfe8161579c565b8114615d0957600080fd5b50565b615d15816157ae565b8114615d2057600080fd5b50565b615d2c816157c0565b8114615d3757600080fd5b50565b615d43816157cc565b8114615d4e57600080fd5b50565b615d5a816157d6565b8114615d6557600080fd5b50565b615d71816157e8565b8114615d7c57600080fd5b50565b615d88816157f5565b8114615d9357600080fd5b50565b615d9f81615831565b8114615daa57600080fd5b50565b615db68161583b565b8114615dc157600080fd5b50565b615dcd8161584b565b8114615dd857600080fd5b5056fea264697066735822122082bc7793ae0219447eaf2dfaba23d19ed773da79a1467d7c9e11eafff30aa74564736f6c634300080300330000000000000000000000003e14dc1b13c488a8d5d310918780c983bd5982e70000000000000000000000006eee6060f715257b970700bc2656de21dedf074c000000000000000000000000b0aabba4b2783a72c52956cdef62d438eca2d7a10000000000000000000000004086ebf75233e8492f1bcda41c7f2a8288c2fb92000000000000000000000000caa7349cea390f89641fe306d93591f87595dc1f000000000000000000000000263026e7e53dbfdce5ae55ade22493f828922965000000000000000000000000a5e0829caced8ffdd4de3c43696c57f7d7a678ff000000000000000000000000acc2d27400029904919ea54ffc0b18bf07c57875000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000167269636f636865746674772d30333039323032312d3400000000000000000000
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000003e14dc1b13c488a8d5d310918780c983bd5982e70000000000000000000000006eee6060f715257b970700bc2656de21dedf074c000000000000000000000000b0aabba4b2783a72c52956cdef62d438eca2d7a10000000000000000000000004086ebf75233e8492f1bcda41c7f2a8288c2fb92000000000000000000000000caa7349cea390f89641fe306d93591f87595dc1f000000000000000000000000263026e7e53dbfdce5ae55ade22493f828922965000000000000000000000000a5e0829caced8ffdd4de3c43696c57f7d7a678ff000000000000000000000000acc2d27400029904919ea54ffc0b18bf07c57875000000000000000000000000000000000000000000000000000000000000003c000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000167269636f636865746674772d30333039323032312d3400000000000000000000
-----Decoded View---------------
Arg [0] : host (address): 0x3e14dc1b13c488a8d5d310918780c983bd5982e7
Arg [1] : cfa (address): 0x6eee6060f715257b970700bc2656de21dedf074c
Arg [2] : ida (address): 0xb0aabba4b2783a72c52956cdef62d438eca2d7a1
Arg [3] : inputToken (address): 0x4086ebf75233e8492f1bcda41c7f2a8288c2fb92
Arg [4] : outputToken (address): 0xcaa7349cea390f89641fe306d93591f87595dc1f
Arg [5] : subsidyToken (address): 0x263026e7e53dbfdce5ae55ade22493f828922965
Arg [6] : sushiRouter (address): 0xa5e0829caced8ffdd4de3c43696c57f7d7a678ff
Arg [7] : oracle (address): 0xacc2d27400029904919ea54ffc0b18bf07c57875
Arg [8] : requestId (uint256): 60
Arg [9] : registrationKey (string): ricochetftw-03092021-4
-----Encoded View---------------
12 Constructor Arguments found :
Arg [0] : 0000000000000000000000003e14dc1b13c488a8d5d310918780c983bd5982e7
Arg [1] : 0000000000000000000000006eee6060f715257b970700bc2656de21dedf074c
Arg [2] : 000000000000000000000000b0aabba4b2783a72c52956cdef62d438eca2d7a1
Arg [3] : 0000000000000000000000004086ebf75233e8492f1bcda41c7f2a8288c2fb92
Arg [4] : 000000000000000000000000caa7349cea390f89641fe306d93591f87595dc1f
Arg [5] : 000000000000000000000000263026e7e53dbfdce5ae55ade22493f828922965
Arg [6] : 000000000000000000000000a5e0829caced8ffdd4de3c43696c57f7d7a678ff
Arg [7] : 000000000000000000000000acc2d27400029904919ea54ffc0b18bf07c57875
Arg [8] : 000000000000000000000000000000000000000000000000000000000000003c
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000140
Arg [10] : 0000000000000000000000000000000000000000000000000000000000000016
Arg [11] : 7269636f636865746674772d30333039323032312d3400000000000000000000
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.