Contract Overview
My Name Tag:
Not Available, login to update
[ Download CSV Export ]
Similar Match Source Code
Note: This contract matches the deployed ByteCode of the Source Code for Contract 0x86c2B55bf5d3E9DAC2747389B38D41C6B1F34179
Contract Name:
REXTwoWayMarket
Compiler Version
v0.8.4+commit.c7e474f2
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: AGPLv3 pragma solidity ^0.8.0; import "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "./REXMarket.sol"; contract REXTwoWayMarket is REXMarket { using SafeERC20 for ERC20; ISuperToken inputTokenA; ISuperToken inputTokenB; uint32 constant OUTPUTA_INDEX = 0; uint32 constant OUTPUTB_INDEX = 1; uint32 constant SUBSIDYA_INDEX = 2; uint32 constant SUBSIDYB_INDEX = 3; uint256 lastDistributionTokenAAt; uint256 lastDistributionTokenBAt; address public constant ric = 0x263026E7e53DBFDce5ae55Ade22493f828922965; ISuperToken subsidyToken; uint256 ricRequestId = 77; IUniswapV2Router02 router = IUniswapV2Router02(0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506); ITellor tellor = ITellor(0xACC2d27400029904919ea54fFc0b18Bf07C57875); // REX Two Way Market Contracts // - Swaps the accumulated input tokens for output tokens constructor( address _owner, ISuperfluid _host, IConstantFlowAgreementV1 _cfa, IInstantDistributionAgreementV1 _ida, string memory _registrationKey, IREXReferral _rexReferral ) REXMarket(_owner, _host, _cfa, _ida, _registrationKey, _rexReferral) {} function initializeTwoWayMarket( ISuperToken _inputTokenA, uint256 _inputTokenARequestId, uint128 _inputTokenAShareScaler, ISuperToken _inputTokenB, uint256 _inputTokenBRequestId, uint128 _inputTokenBShareScaler, uint128 _feeRate, uint256 _rateTolerance ) public onlyOwner initializer { inputTokenA = _inputTokenA; inputTokenB = _inputTokenB; market.inputToken = _inputTokenA; // market.inputToken isn't used but is set bc of the REXMarket market.rateTolerance = _rateTolerance; oracle = tellor; market.feeRate = _feeRate; market.affiliateFee = 500000; require( _inputTokenAShareScaler >= 1e6 && _inputTokenBShareScaler >= 1e6, "!scaleable" ); addOutputPool( inputTokenA, _feeRate, 0, _inputTokenARequestId, _inputTokenAShareScaler ); addOutputPool( inputTokenB, _feeRate, 0, _inputTokenBRequestId, _inputTokenBShareScaler ); market.outputPoolIndicies[inputTokenA] = OUTPUTA_INDEX; market.outputPoolIndicies[inputTokenB] = OUTPUTB_INDEX; // Approvals for sushiswap and upgrading tokens address inputTokenAUnderlying = address( inputTokenA.getUnderlyingToken() ); address inputTokenBUnderlying = address( inputTokenB.getUnderlyingToken() ); if (inputTokenAUnderlying == address(0)) { // inputTokenA is supertoken, approve swap router for it inputTokenAUnderlying = address(inputTokenA); } else { // otherwise approve underlying for upgrade ERC20(inputTokenAUnderlying).safeIncreaseAllowance( address(inputTokenA), 2**256 - 1 ); } if (inputTokenBUnderlying == address(0)) { // inputTokenB is supertoken, approve swap router for it inputTokenBUnderlying = address(inputTokenB); } else { // otherwise approve underlying for upgrade ERC20(inputTokenBUnderlying).safeIncreaseAllowance( address(inputTokenB), 2**256 - 1 ); } ERC20(inputTokenAUnderlying).safeIncreaseAllowance( address(router), 2**256 - 1 ); ERC20(inputTokenBUnderlying).safeIncreaseAllowance( address(router), 2**256 - 1 ); market.lastDistributionAt = block.timestamp; } function initializeSubsidies( uint256 _emissionRate, ISuperToken _subsidyToken ) public onlyOwner { subsidyToken = _subsidyToken; require( address(market.outputPools[SUBSIDYA_INDEX].token) == address(0) && address(market.outputPools[SUBSIDYB_INDEX].token) == address(0), "already initialized" ); addOutputPool( _subsidyToken, 0, _emissionRate, 77, market.outputPools[OUTPUTB_INDEX].shareScaler ); addOutputPool( _subsidyToken, 0, _emissionRate, 77, market.outputPools[OUTPUTA_INDEX].shareScaler ); lastDistributionTokenAAt = block.timestamp; lastDistributionTokenBAt = block.timestamp; // Does not need to add subsidy token to outputPoolIndicies // since these pools are hardcoded } function addOutputPool( ISuperToken _token, uint128 _feeRate, uint256 _emissionRate, uint256 _requestId, uint128 _shareScaler ) public override onlyOwner { // Only Allow 4 output pools, this overrides the block in REXMarket // where there can't be two output pools of the same token require(market.numOutputPools < 4, "too many pools"); OutputPool memory _newPool = OutputPool( _token, _feeRate, _emissionRate, _shareScaler ); market.outputPools[market.numOutputPools] = _newPool; market.outputPoolIndicies[_token] = market.numOutputPools; _createIndex(market.numOutputPools, _token); market.numOutputPools++; OracleInfo memory _newOracle = OracleInfo(_requestId, 0, 0); market.oracles[_token] = _newOracle; updateTokenPrice(_token); } function distribute(bytes memory ctx) public override returns (bytes memory newCtx) { newCtx = ctx; require( market .oracles[market.outputPools[OUTPUTA_INDEX].token] .lastUpdatedAt >= block.timestamp - 3600, "!currentValueA" ); require( market .oracles[market.outputPools[OUTPUTB_INDEX].token] .lastUpdatedAt >= block.timestamp - 3600, "!currentValueB" ); // At this point, we've got enough of tokenA and tokenB to perform the distribution uint256 tokenAAmount = inputTokenA.balanceOf(address(this)); uint256 tokenBAmount = inputTokenB.balanceOf(address(this)); // Check how much inputTokenA we have already from tokenB uint256 tokenHave = (tokenBAmount * market.oracles[inputTokenB].usdPrice) / market.oracles[inputTokenA].usdPrice; // If we have more tokenA than we need, swap the surplus to inputTokenB if (tokenHave < tokenAAmount) { tokenHave = tokenAAmount - tokenHave; _swap(inputTokenA, inputTokenB, tokenHave, block.timestamp + 3600); // Otherwise we have more tokenB than we need, swap the surplus to inputTokenA } else { tokenHave = (tokenAAmount * market.oracles[inputTokenA].usdPrice) / market.oracles[inputTokenB].usdPrice; tokenHave = tokenBAmount - tokenHave; _swap(inputTokenB, inputTokenA, tokenHave, block.timestamp + 3600); } // At this point, we've got enough of tokenA and tokenB to perform the distribution tokenAAmount = inputTokenA.balanceOf(address(this)); tokenBAmount = inputTokenB.balanceOf(address(this)); if (tokenAAmount == 0 && tokenBAmount == 0) { return newCtx; } // Perform the distributions uint256 feeCollected; uint256 distAmount; (, , uint128 _totalUnitsApproved, uint128 _totalUnitsPending) = ida .getIndex( market.outputPools[OUTPUTA_INDEX].token, address(this), OUTPUTA_INDEX ); if (tokenAAmount > 0 && _totalUnitsApproved + _totalUnitsPending > 0) { (tokenAAmount, ) = ida.calculateDistribution( inputTokenA, address(this), OUTPUTA_INDEX, tokenAAmount ); // Distribute TokenA require( inputTokenA.balanceOf(address(this)) >= tokenAAmount, "!enough" ); newCtx = _idaDistribute( OUTPUTA_INDEX, uint128(tokenAAmount), inputTokenA, newCtx ); emit Distribution(distAmount, feeCollected, address(inputTokenA)); // Distribution Subsidy distAmount = (block.timestamp - lastDistributionTokenAAt) * market.outputPools[SUBSIDYA_INDEX].emissionRate; if ( distAmount < market.outputPools[SUBSIDYA_INDEX].token.balanceOf( address(this) ) ) { newCtx = _idaDistribute( SUBSIDYA_INDEX, uint128(distAmount), market.outputPools[SUBSIDYA_INDEX].token, newCtx ); emit Distribution( distAmount, 0, address(market.outputPools[SUBSIDYA_INDEX].token) ); } lastDistributionTokenAAt = block.timestamp; } (, , _totalUnitsApproved, _totalUnitsPending) = ida.getIndex( market.outputPools[OUTPUTB_INDEX].token, address(this), OUTPUTB_INDEX ); if (tokenBAmount > 0 && _totalUnitsApproved + _totalUnitsPending > 0) { (tokenBAmount, ) = ida.calculateDistribution( inputTokenB, address(this), OUTPUTB_INDEX, tokenBAmount ); // Distribute TokenB require( inputTokenB.balanceOf(address(this)) >= tokenBAmount, "!enough" ); newCtx = _idaDistribute( OUTPUTB_INDEX, uint128(tokenBAmount), inputTokenB, newCtx ); emit Distribution(distAmount, feeCollected, address(inputTokenB)); // Distribution Subsidy distAmount = (block.timestamp - lastDistributionTokenBAt) * market.outputPools[SUBSIDYB_INDEX].emissionRate; if ( distAmount < market.outputPools[SUBSIDYB_INDEX].token.balanceOf( address(this) ) ) { newCtx = _idaDistribute( SUBSIDYB_INDEX, uint128(distAmount), market.outputPools[SUBSIDYB_INDEX].token, newCtx ); emit Distribution( distAmount, 0, address(market.outputPools[SUBSIDYB_INDEX].token) ); } lastDistributionTokenBAt = block.timestamp; } market.lastDistributionAt = block.timestamp; } function beforeAgreementCreated( ISuperToken _superToken, address _agreementClass, bytes32, //_agreementId, bytes calldata _agreementData, bytes calldata _ctx ) external view virtual override returns (bytes memory _cbdata) { _onlyHost(); if (!_isInputToken(_superToken) || !_isCFAv1(_agreementClass)) return _ctx; (address shareholder, ) = abi.decode( _agreementData, (address, address) ); (, , uint128 shares, ) = getIDAShares(OUTPUTA_INDEX, shareholder); require(shares == 0, "Already streaming"); (, , shares, ) = getIDAShares(OUTPUTB_INDEX, shareholder); require(shares == 0, "Already streaming"); } function beforeAgreementTerminated( ISuperToken _superToken, address _agreementClass, bytes32, //_agreementId, bytes calldata _agreementData, bytes calldata _ctx ) external view virtual override returns (bytes memory _cbdata) { _onlyHost(); if (!_isInputToken(_superToken) || !_isCFAv1(_agreementClass)) return _ctx; ( address _shareholder, int96 _flowRateMain, uint256 _timestamp ) = _getShareholderInfo(_agreementData, _superToken); uint256 _uinvestAmount = _calcUserUninvested( _timestamp, uint256(uint96(_flowRateMain)), // Select the correct lastDistributionAt for this _superToken _getLastDistributionAt(_superToken) ); _cbdata = abi.encode(_uinvestAmount, int256(_flowRateMain)); } function _swap( ISuperToken input, ISuperToken output, uint256 amount, uint256 deadline ) internal returns (uint256) { 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 = input.getUnderlyingToken(); outputToken = output.getUnderlyingToken(); // Downgrade and scale the input amount // Handle case input or output is native supertoken if (inputToken == address(0)) { inputToken = address(input); } else { input.downgrade(amount); // Scale it to 1e18 for calculations amount = ERC20(inputToken).balanceOf(address(this)) * (10**(18 - ERC20(inputToken).decimals())); } if (outputToken == address(0)) { outputToken = address(output); } minOutput = (amount * market.oracles[input].usdPrice) / market.oracles[output].usdPrice; minOutput = (minOutput * (1e6 - market.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())); // Assumes a direct path to swap input/output path = new address[](2); path[0] = inputToken; path[1] = outputToken; router.swapExactTokensForTokens( amount, minOutput, // 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 if needed if (address(output) != outputToken) { output.upgrade( ERC20(outputToken).balanceOf(address(this)) * (10**(18 - ERC20(outputToken).decimals())) ); } return outputAmount; } function _updateShareholder( bytes memory _ctx, ShareholderUpdate memory _shareholderUpdate ) internal override returns (bytes memory _newCtx) { // Check the input supertoken used and figure out the output Index // inputTokenA maps the OUTPUTB_INDEX // maybe a better way to do this uint32 outputIndex; uint32 subsidyIndex; if ( market.outputPoolIndicies[_shareholderUpdate.token] == OUTPUTA_INDEX ) { outputIndex = OUTPUTB_INDEX; subsidyIndex = SUBSIDYB_INDEX; _shareholderUpdate.token = inputTokenB; } else { outputIndex = OUTPUTA_INDEX; subsidyIndex = SUBSIDYA_INDEX; _shareholderUpdate.token = inputTokenA; } ( uint128 userShares, uint128 daoShares, uint128 affiliateShares ) = _getShareAllocations(_shareholderUpdate); _newCtx = _ctx; // TODO: Update the fee taken by the DAO, Affiliate _newCtx = _updateSubscriptionWithContext( _newCtx, outputIndex, _shareholderUpdate.shareholder, userShares, market.outputPools[outputIndex].token ); _newCtx = _updateSubscriptionWithContext( _newCtx, subsidyIndex, _shareholderUpdate.shareholder, userShares, subsidyToken ); _newCtx = _updateSubscriptionWithContext( _newCtx, outputIndex, owner(), daoShares, market.outputPools[outputIndex].token ); // Owner is not added to subsidy pool address affiliate = referrals.getAffiliateAddress( _shareholderUpdate.shareholder ); if (affiliate != address(0)) { _newCtx = _updateSubscriptionWithContext( _newCtx, outputIndex, affiliate, affiliateShares, market.outputPools[outputIndex].token ); _newCtx = _updateSubscriptionWithContext( _newCtx, subsidyIndex, affiliate, affiliateShares, subsidyToken ); } } function _isInputToken(ISuperToken _superToken) internal view override returns (bool) { return address(_superToken) == address(inputTokenA) || address(_superToken) == address(inputTokenB); } function _getLastDistributionAt(ISuperToken _token) internal view returns (uint256) { return market.outputPoolIndicies[_token] == OUTPUTA_INDEX ? lastDistributionTokenBAt : lastDistributionTokenAAt; } function _shouldDistribute() internal override returns (bool) { // TODO: This section should be checked, // since it only checks one IDA, (, , uint128 _totalUnitsApproved, uint128 _totalUnitsPending) = ida .getIndex( market.outputPools[OUTPUTA_INDEX].token, address(this), OUTPUTA_INDEX ); if (_totalUnitsApproved + _totalUnitsPending > 0) { (, , _totalUnitsApproved, _totalUnitsPending) = ida.getIndex( market.outputPools[OUTPUTB_INDEX].token, address(this), OUTPUTB_INDEX ); if (_totalUnitsApproved + _totalUnitsPending > 0) { return true; } } return false; } function _onlyScalable(ISuperToken _superToken, int96 _flowRate) internal override { if (market.outputPoolIndicies[_superToken] == OUTPUTA_INDEX) { require( uint128(uint256(int256(_flowRate))) % (market.outputPools[OUTPUTB_INDEX].shareScaler * 1e3) == 0, "notScalable" ); } else { require( uint128(uint256(int256(_flowRate))) % (market.outputPools[OUTPUTA_INDEX].shareScaler * 1e3) == 0, "notScalable" ); } } }
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 // OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: AGPLv3 pragma solidity ^0.8.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 {SuperAppBase} from "@superfluid-finance/ethereum-contracts/contracts/apps/SuperAppBase.sol"; import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol"; import "./tellor/ITellor.sol"; import "./referral/IREXReferral.sol"; import "hardhat/console.sol"; // solhint-disable not-rely-on-time abstract contract REXMarket is Ownable, SuperAppBase, Initializable { // REX Market Base Contract // // Responsibilities: // - Reusable superfluid functionality // - Oracle management functionality // - IDA pool share management functionality // // Deployment Sequence: // - Construct the contract with the Superfluid and owner info // - Initialize the input token and props (initializeMarket) // - Add first output pool which is the main output token sent (addOutputPool) // - Add second output pool which is the subsidy token send (addOutputPool) // // Extending REX Markets: // - Contract should be extended and the extending contract should override: // - distribute() - must take accumulated input tokens, convert to // output tokens and distribute to output pool // - harvest() - (optional) must harvest yield, aggregate it such so that // the distrute method can distribute it struct ShareholderUpdate { address shareholder; int96 previousFlowRate; int96 currentFlowRate; ISuperToken token; } struct OracleInfo { uint256 requestId; uint256 usdPrice; uint256 lastUpdatedAt; } struct OutputPool { ISuperToken token; uint128 feeRate; // Fee taken by the DAO on each output distribution uint256 emissionRate; // Rate to emit tokens if there's a balance, used for subsidies uint128 shareScaler; // The amount to scale back IDA shares of this output pool } struct Market { ISuperToken inputToken; uint256 lastDistributionAt; // The last time a distribution was made uint256 rateTolerance; // The percentage to deviate from the oracle scaled to 1e6 uint128 feeRate; uint128 affiliateFee; address owner; // The owner of the market (reciever of fees) mapping(ISuperToken => OracleInfo) oracles; // Maps tokens to their oracle info mapping(uint32 => OutputPool) outputPools; // Maps IDA indexes to their distributed Supertokens mapping(ISuperToken => uint32) outputPoolIndicies; // Maps tokens to their IDA indexes in OutputPools uint8 numOutputPools; // Indexes outputPools and outputPoolFees } ISuperfluid internal host; // Superfluid host contract IConstantFlowAgreementV1 internal cfa; // The stored constant flow agreement class address IInstantDistributionAgreementV1 internal ida; // The stored instant dist. agreement class address ITellor public oracle; // Address of deployed simple oracle for input//output token Market internal market; uint32 internal constant PRIMARY_OUTPUT_INDEX = 0; uint8 internal constant MAX_OUTPUT_POOLS = 5; IREXReferral internal referrals; // TODO: Emit these events where appropriate /// @dev Distribution event. Emitted on each token distribution operation. /// @param totalAmount is total distributed amount /// @param feeCollected is fee amount collected during distribution /// @param token is distributed token address event Distribution( uint256 totalAmount, uint256 feeCollected, address token ); constructor( address _owner, ISuperfluid _host, IConstantFlowAgreementV1 _cfa, IInstantDistributionAgreementV1 _ida, string memory _registrationKey, IREXReferral _rexReferral ) { host = _host; cfa = _cfa; ida = _ida; referrals = _rexReferral; transferOwnership(_owner); uint256 _configWord = SuperAppDefinitions.APP_LEVEL_FINAL; if (bytes(_registrationKey).length > 0) { host.registerAppWithKey(_configWord, _registrationKey); } else { host.registerApp(_configWord); } } /// @dev Allows anyone to close any stream if the app is jailed. /// @param streamer is stream source (streamer) address function emergencyCloseStream(address streamer, ISuperToken token) external virtual { // Allows anyone to close any stream if the app is jailed require(host.isAppJailed(ISuperApp(address(this))), "!jailed"); host.callAgreement( cfa, abi.encodeWithSelector( cfa.deleteFlow.selector, token, streamer, address(this), new bytes(0) // placeholder ), "0x" ); } /// @dev Close stream from `streamer` address if balance is less than 8 hours of streaming /// @param streamer is stream source (streamer) address function closeStream(address streamer, ISuperToken token) public { // Only closable iff their balance is less than 8 hours of streaming (,int96 streamerFlowRate,,) = cfa.getFlow(token, streamer, address(this)); // int96 streamerFlowRate = getStreamRate(token, streamer); require(int(token.balanceOf(streamer)) <= streamerFlowRate * 8 hours, "!closable"); // Close the streamers stream // Does this trigger before/afterAgreementTerminated host.callAgreement( cfa, abi.encodeWithSelector( cfa.deleteFlow.selector, token, streamer, address(this), new bytes(0) // placeholder ), "0x" ); } /// @dev Drain contract's input and output tokens balance to owner if SuperApp dont have any input streams. function emergencyDrain(ISuperToken token) external virtual onlyOwner { require( cfa.getNetFlow(token, address(this)) == 0, "!zeroStreamers" ); require(host.isAppJailed(ISuperApp(address(this))), "!jailed"); token.transfer( owner(), token.balanceOf(address(this)) ); } /// @dev Set rate tolerance /// @param _rate This is the new rate we need to set to function setRateTolerance(uint256 _rate) external onlyOwner { market.rateTolerance = _rate; } /// @dev Sets fee rate for a output pool/token /// @param _index IDA index for the output pool/token /// @param _feeRate Fee rate for the output pool/token function setFeeRate(uint32 _index, uint128 _feeRate) external onlyOwner { market.outputPools[_index].feeRate = _feeRate; } /// @dev Sets emission rate for a output pool/token /// @param _index IDA index for the output pool/token /// @param _emissionRate Emission rate for the output pool/token function setEmissionRate(uint32 _index, uint128 _emissionRate) external onlyOwner { market.outputPools[_index].emissionRate = _emissionRate; } // Getters /// @dev Get input token address /// @return input token address function getInputToken() external view returns (ISuperToken) { return market.inputToken; } /// @dev Get output token address /// @return output token address function getOutputPool(uint32 _index) external view returns (OutputPool memory) { return market.outputPools[_index]; } /// @dev Get output token address /// @return output token address function getOracleInfo(ISuperToken token) external view returns (OracleInfo memory) { return market.oracles[token]; } /// @dev Get last distribution timestamp /// @return last distribution timestamp function getLastDistributionAt() external view returns (uint256) { return market.lastDistributionAt; } /// @dev Is app jailed in SuperFluid protocol /// @return is app jailed in SuperFluid protocol function isAppJailed() external view returns (bool) { return host.isAppJailed(this); } /// @dev Get rate tolerance /// @return Rate tolerance scaled to 1e6 function getRateTolerance() external view returns (uint256) { return market.rateTolerance; } /// @dev Get fee rate for a given output pool/token /// @param _index IDA index for the output pool/token /// @return Fee rate for the output pool function getFeeRate(uint32 _index) external view returns (uint128) { return market.outputPools[_index].feeRate; } /// @dev Get emission rate for a given output pool/token /// @param _index IDA index for the output pool/token /// @return Emission rate for the output pool function getEmissionRate(uint32 _index) external view returns (uint256) { return market.outputPools[_index].emissionRate; } // Custom functionality that needs to be overrided by contract extending the base // Converts input token to output token function distribute(bytes memory _ctx) public virtual returns (bytes memory _newCtx); // Market initialization methods function initializeMarket( ISuperToken _inputToken, uint256 _rateTolerance, ITellor _tellor, uint256 _inputTokenRequestId, uint128 _affiliateFee, uint128 _feeRate ) public virtual onlyOwner { require( address(market.inputToken) == address(0), "Already initialized" ); market.inputToken = _inputToken; market.rateTolerance = _rateTolerance; market.affiliateFee = _affiliateFee; market. feeRate = _feeRate; oracle = _tellor; OracleInfo memory _newOracle = OracleInfo(_inputTokenRequestId, 0, 0); market.oracles[market.inputToken] = _newOracle; updateTokenPrice(_inputToken); } function addOutputPool( ISuperToken _token, uint128 _feeRate, uint256 _emissionRate, uint256 _requestId, uint128 _shareScaler ) public virtual onlyOwner { // NOTE: Careful how many output pools, theres a loop over these pools require(_requestId != 0, "!validReqId"); require(market.oracles[_token].requestId == 0, "!unique"); require(market.numOutputPools < MAX_OUTPUT_POOLS, "Too many pools"); OutputPool memory _newPool = OutputPool( _token, _feeRate, _emissionRate, _shareScaler ); market.outputPools[market.numOutputPools] = _newPool; market.outputPoolIndicies[_token] = market.numOutputPools; _createIndex(market.numOutputPools, _token); market.numOutputPools++; OracleInfo memory _newOracle = OracleInfo(_requestId, 0, 0); market.oracles[_token] = _newOracle; updateTokenPrice(_token); } // Standardized functionality for all REX Markets // Oracle Functions function updateTokenPrices() public { updateTokenPrice(market.inputToken); for (uint32 index = 0; index < market.numOutputPools; index++) { updateTokenPrice(market.outputPools[index].token); } } function updateTokenPrice(ISuperToken _token) public { ( bool _ifRetrieve, uint256 _value, uint256 _timestampRetrieved ) = getCurrentValue(market.oracles[_token].requestId); require(_ifRetrieve, "!getCurrentValue"); require(_timestampRetrieved >= block.timestamp - 3600, "!currentValue"); market.oracles[_token].usdPrice = _value; market.oracles[_token].lastUpdatedAt = _timestampRetrieved; } function getCurrentValue(uint256 _requestId) public view returns ( bool _ifRetrieve, uint256 _value, uint256 _timestampRetrieved ) { uint256 _count = oracle.getNewValueCountbyRequestId(_requestId); _timestampRetrieved = oracle.getTimestampbyRequestIDandIndex( _requestId, _count - 1 ); _value = oracle.retrieveData(_requestId, _timestampRetrieved); if (_value > 0) return (true, _value, _timestampRetrieved); return (false, 0, _timestampRetrieved); } /// @dev Get flow rate for `_streamer` /// @param _streamer is streamer address /// @return _requesterFlowRate `_streamer` flow rate function getStreamRate(address _streamer, ISuperToken _token) external view returns (int96 _requesterFlowRate) { (, _requesterFlowRate, , ) = cfa.getFlow( _token, _streamer, address(this) ); } /// @dev Get `_streamer` IDA subscription info for token with index `_index` /// @param _index is token index in IDA /// @param _streamer is streamer address /// @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 getIDAShares(uint32 _index, address _streamer) public view returns ( bool _exist, bool _approved, uint128 _units, uint256 _pendingDistribution ) { (_exist, _approved, _units, _pendingDistribution) = ida.getSubscription( market.outputPools[_index].token, address(this), _index, _streamer ); } function _updateShareholder( bytes memory _ctx, ShareholderUpdate memory _shareholderUpdate ) internal virtual returns (bytes memory _newCtx) { // We need to go through all the output tokens and update their IDA shares _newCtx = _ctx; (uint128 userShares, uint128 daoShares, uint128 affiliateShares) = _getShareAllocations(_shareholderUpdate); // updateOutputPools for (uint32 _index = 0; _index < market.numOutputPools; _index++) { _newCtx = _updateSubscriptionWithContext( _newCtx, _index, _shareholderUpdate.shareholder, // shareholder gets 98% of the units, DAO takes 0.02% userShares, market.outputPools[_index].token ); _newCtx = _updateSubscriptionWithContext( _newCtx, _index, owner(), // shareholder gets 98% of the units, DAO takes 2% daoShares, market.outputPools[_index].token ); address affiliate = referrals.getAffiliateAddress(_shareholderUpdate.shareholder); if (affiliate != address(0)) { _newCtx = _updateSubscriptionWithContext( _newCtx, _index, affiliate, // affiliate may get 0.2% affiliateShares, market.outputPools[_index].token ); } // TODO: Update the fee taken by the DAO } } function _getShareAllocations(ShareholderUpdate memory _shareholderUpdate) internal returns (uint128 userShares, uint128 daoShares, uint128 affiliateShares) { (,,daoShares,) = getIDAShares(market.outputPoolIndicies[_shareholderUpdate.token], owner()); daoShares *= market.outputPools[market.outputPoolIndicies[_shareholderUpdate.token]].shareScaler; address affiliateAddress = referrals.getAffiliateAddress(_shareholderUpdate.shareholder); if (address(0) != affiliateAddress) { (,,affiliateShares,) = getIDAShares(market.outputPoolIndicies[_shareholderUpdate.token], affiliateAddress); affiliateShares *= market.outputPools[market.outputPoolIndicies[_shareholderUpdate.token]].shareScaler; } // Compute the change in flow rate, will be negative is slowing the flow rate int96 changeInFlowRate = _shareholderUpdate.currentFlowRate - _shareholderUpdate.previousFlowRate; uint128 feeShares; // if the change is positive value then DAO has some new shares, // which would be 2% of the increase in shares if(changeInFlowRate > 0) { // Add new shares to the DAO feeShares = uint128(uint256(int256(changeInFlowRate)) * market.feeRate / 1e6); if (address(0) != affiliateAddress) { affiliateShares += feeShares * market.affiliateFee / 1e6; feeShares -= feeShares * market.affiliateFee / 1e6; } daoShares += feeShares; } else { // Make the rate positive changeInFlowRate = -1 * changeInFlowRate; feeShares = uint128(uint256(int256(changeInFlowRate)) * market.feeRate / 1e6); if (address(0) != affiliateAddress) { affiliateShares -= (feeShares * market.affiliateFee / 1e6 > affiliateShares) ? affiliateShares : feeShares * market.affiliateFee / 1e6; feeShares -= feeShares * market.affiliateFee / 1e6; } daoShares -= (feeShares > daoShares) ? daoShares : feeShares; } userShares = uint128(uint256(int256(_shareholderUpdate.currentFlowRate))) * (1e6 - market.feeRate) / 1e6; // Scale back shares affiliateShares /= market.outputPools[market.outputPoolIndicies[_shareholderUpdate.token]].shareScaler; daoShares /= market.outputPools[market.outputPoolIndicies[_shareholderUpdate.token]].shareScaler; userShares /= market.outputPools[market.outputPoolIndicies[_shareholderUpdate.token]].shareScaler; } function _getShareholderInfo(bytes calldata _agreementData, ISuperToken _superToken) internal view returns (address _shareholder, int96 _flowRate, uint256 _timestamp) { (_shareholder, ) = abi.decode(_agreementData, (address, address)); (_timestamp, _flowRate, , ) = cfa.getFlow( _superToken, _shareholder, address(this) ); } /// @dev Distributes `_distAmount` amount of `_distToken` token among all IDA index subscribers /// @param _index IDA index ID /// @param _distAmount amount to distribute /// @param _distToken distribute token address /// @param _ctx SuperFluid context data /// @return _newCtx updated SuperFluid context data function _idaDistribute( uint32 _index, uint128 _distAmount, ISuperToken _distToken, bytes memory _ctx ) internal returns (bytes memory _newCtx) { _newCtx = _ctx; if (_newCtx.length == 0) { // No context provided host.callAgreement( ida, abi.encodeWithSelector( ida.distribute.selector, _distToken, _index, _distAmount, new bytes(0) // placeholder ctx ), new bytes(0) // user data ); } else { (_newCtx, ) = host.callAgreementWithContext( ida, abi.encodeWithSelector( ida.distribute.selector, _distToken, _index, _distAmount, new bytes(0) // placeholder ctx ), new bytes(0), // user data _newCtx ); } } // Superfluid Agreement Management Methods function _createIndex(uint256 index, ISuperToken distToken) internal { host.callAgreement( ida, abi.encodeWithSelector( ida.createIndex.selector, distToken, index, new bytes(0) // placeholder ctx ), new bytes(0) // user data ); } /// @dev Set new `shares` share for `subscriber` address in IDA with `index` index /// @param index IDA index ID /// @param subscriber is subscriber address /// @param shares is distribution shares count /// @param distToken is distribution token address function _updateSubscription( uint256 index, address subscriber, uint128 shares, ISuperToken distToken ) internal { host.callAgreement( ida, abi.encodeWithSelector( ida.updateSubscription.selector, distToken, index, subscriber, shares, new bytes(0) // placeholder ctx ), new bytes(0) // user data ); } /// @dev Same as _updateSubscription but uses provided SuperFluid context data /// @param ctx SuperFluid context data /// @param index IDA index ID /// @param subscriber is subscriber address /// @param shares is distribution shares count /// @param distToken is distribution token address /// @return newCtx updated SuperFluid context data function _updateSubscriptionWithContext( bytes memory ctx, uint256 index, address subscriber, uint128 shares, ISuperToken distToken ) internal returns (bytes memory newCtx) { newCtx = ctx; (newCtx, ) = host.callAgreementWithContext( ida, abi.encodeWithSelector( ida.updateSubscription.selector, distToken, index, subscriber, shares, new bytes(0) ), new bytes(0), // user data newCtx ); } // internal helper function to get the amount that needs to be returned back to the user function _calcUserUninvested( uint256 _prevUpdateTimestamp, uint256 _flowRate, uint256 _lastDistributedAt ) internal view returns (uint256 _uninvestedAmount) { _uninvestedAmount = _flowRate * (block.timestamp - ( (_prevUpdateTimestamp > _lastDistributedAt) ? _prevUpdateTimestamp : _lastDistributedAt )); } // Boolean Helpers function _isInputToken(ISuperToken _superToken) internal virtual view returns (bool) { return address(_superToken) == address(market.inputToken); } function _isOutputToken(ISuperToken _superToken) internal view returns (bool) { return market.outputPools[market.outputPoolIndicies[_superToken]].token == _superToken; } function _isCFAv1(address _agreementClass) internal view returns (bool) { return ISuperAgreement(_agreementClass).agreementType() == keccak256( "org.superfluid-finance.agreements.ConstantFlowAgreement.v1" ); } function _isIDAv1(address _agreementClass) internal view returns (bool) { return ISuperAgreement(_agreementClass).agreementType() == keccak256( "org.superfluid-finance.agreements.InstantDistributionAgreement.v1" ); } /// @dev Restricts calls to only from SuperFluid host function _onlyHost() internal view { require(msg.sender == address(host), "!host"); } function _shouldDistribute() internal virtual returns (bool) { (, , uint128 _totalUnitsApproved, uint128 _totalUnitsPending) = ida .getIndex( market.outputPools[PRIMARY_OUTPUT_INDEX].token, address(this), PRIMARY_OUTPUT_INDEX ); // Check balance and account for just 1 input token uint256 _balance = market.inputToken.balanceOf( address(this) ); return _totalUnitsApproved + _totalUnitsPending > 0 && _balance > 0; } function _onlyScalable(ISuperToken _superToken, int96 _flowRate) internal virtual { // Enforce speed limit on flowRate require(uint128(uint(int(_flowRate))) % (market.outputPools[market.outputPoolIndicies[_superToken]].shareScaler * 1e3) == 0, "notScalable"); } function _registerReferral(bytes memory _ctx, address _shareholder) internal { require(referrals.addressToAffiliate(_shareholder) == 0, "noAffiliates"); ISuperfluid.Context memory decompiledContext = host.decodeCtx(_ctx); string memory affiliateId; if (decompiledContext.userData.length > 0) { (affiliateId) = abi.decode(decompiledContext.userData, (string)); } else { affiliateId = ""; } referrals.safeRegisterCustomer(_shareholder, affiliateId); } // Superfluid Functions function beforeAgreementCreated( ISuperToken _superToken, address _agreementClass, bytes32, //_agreementId, bytes calldata _agreementData, bytes calldata // _ctx ) external view virtual override returns (bytes memory _cbdata) { } function afterAgreementCreated( ISuperToken _superToken, address _agreementClass, bytes32, //_agreementId, bytes calldata _agreementData, bytes calldata, //_cbdata, bytes calldata _ctx ) external virtual override returns (bytes memory _newCtx) { _onlyHost(); if (!_isInputToken(_superToken) || !_isCFAv1(_agreementClass)) return _ctx; _newCtx = _ctx; if (_shouldDistribute()) { _newCtx = distribute(_newCtx); } (address _shareholder, int96 _flowRate, ) = _getShareholderInfo( _agreementData, _superToken ); _onlyScalable(_superToken, _flowRate); _registerReferral(_ctx, _shareholder); ShareholderUpdate memory _shareholderUpdate = ShareholderUpdate( _shareholder, 0, _flowRate, _superToken ); _newCtx = _updateShareholder(_newCtx, _shareholderUpdate); } function beforeAgreementUpdated( ISuperToken _superToken, address _agreementClass, bytes32, //_agreementId, bytes calldata _agreementData, bytes calldata _ctx ) external view virtual override returns (bytes memory _cbdata) { _onlyHost(); if (!_isInputToken(_superToken) || !_isCFAv1(_agreementClass)) return _ctx; // Get the stakeholders current flow rate and save it in cbData (, int96 _flowRate,) = _getShareholderInfo( _agreementData, _superToken ); _cbdata = abi.encode(_flowRate); } function afterAgreementUpdated( ISuperToken _superToken, address _agreementClass, bytes32, //_agreementId, bytes calldata _agreementData, bytes calldata _cbdata, bytes calldata _ctx ) external virtual override returns (bytes memory _newCtx) { _onlyHost(); if (!_isInputToken(_superToken) || !_isCFAv1(_agreementClass)) return _ctx; _newCtx = _ctx; (address _shareholder, int96 _flowRate,) = _getShareholderInfo( _agreementData, _superToken ); _onlyScalable(_superToken, _flowRate); int96 _beforeFlowRate = abi.decode(_cbdata, (int96)); if (_shouldDistribute()) { _newCtx = distribute(_newCtx); } ShareholderUpdate memory _shareholderUpdate = ShareholderUpdate( _shareholder, _beforeFlowRate, _flowRate, _superToken ); // TODO: Udpate shareholder needs before and after flow rate _newCtx = _updateShareholder(_newCtx, _shareholderUpdate); } // We need before agreement to get the uninvested amount using the flowRate before update function beforeAgreementTerminated( ISuperToken _superToken, address _agreementClass, bytes32, //_agreementId, bytes calldata _agreementData, bytes calldata _ctx ) external view virtual override returns (bytes memory _cbdata) { _onlyHost(); if (!_isInputToken(_superToken) || !_isCFAv1(_agreementClass)) return _ctx; (address _shareholder, int96 _flowRateMain, uint256 _timestamp) = _getShareholderInfo(_agreementData, _superToken); uint256 _uinvestAmount = _calcUserUninvested( _timestamp, uint256(uint96(_flowRateMain)), market.lastDistributionAt ); _cbdata = abi.encode(_uinvestAmount, _flowRateMain); } function afterAgreementTerminated( ISuperToken _superToken, address _agreementClass, bytes32, //_agreementId, bytes calldata _agreementData, bytes calldata _cbdata, //_cbdata, bytes calldata _ctx ) external virtual override returns (bytes memory _newCtx) { _onlyHost(); if (!_isInputToken(_superToken) || !_isCFAv1(_agreementClass)) return _ctx; _newCtx = _ctx; (address _shareholder, ) = abi.decode(_agreementData, (address, address)); (uint256 _uninvestAmount, int96 _beforeFlowRate ) = abi.decode(_cbdata, (uint256, int96)); ShareholderUpdate memory _shareholderUpdate = ShareholderUpdate( _shareholder, _beforeFlowRate, 0, _superToken ); _newCtx = _updateShareholder(_newCtx, _shareholderUpdate); // Refund the unswapped amount back to the person who started the stream try _superToken.transferFrom(address(this), _shareholder, _uninvestAmount) // solhint-disable-next-line no-empty-blocks {} catch { // Nothing to do, pass } } }
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 // OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Address.sol) pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: 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"); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/utils/Initializable.sol) pragma solidity ^0.8.0; import "../../utils/Address.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() initializer {} * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { // If the contract is initializing we ignore whether _initialized is set in order to support multiple // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the // contract may have been reentered. require(_initializing ? _isConstructor() : !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} modifier, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } function _isConstructor() private view returns (bool) { return !Address.isContract(address(this)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/ERC20.sol) pragma solidity ^0.8.0; import "./IERC20.sol"; import "./extensions/IERC20Metadata.sol"; import "../../utils/Context.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20 is Context, IERC20, IERC20Metadata { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * Requirements: * * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom( address sender, address recipient, uint256 amount ) public virtual override returns (bool) { _transfer(sender, recipient, amount); uint256 currentAllowance = _allowances[sender][_msgSender()]; require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance"); unchecked { _approve(sender, _msgSender(), currentAllowance - amount); } return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { uint256 currentAllowance = _allowances[_msgSender()][spender]; require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(_msgSender(), spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `sender` to `recipient`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer( address sender, address recipient, uint256 amount ) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); uint256 senderBalance = _balances[sender]; require(senderBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[sender] = senderBalance - amount; } _balances[recipient] += amount; emit Transfer(sender, recipient, amount); _afterTokenTransfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; _balances[account] += amount; emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; } _totalSupply -= amount; emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} }
// 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: MIT pragma solidity ^0.8.0; interface IREXReferral { function addressToAffiliate (address) view external returns (uint256); /** * @dev Add a market contract to allow-list * @param contractAddr address for REXMarket contract */ function registerApp (address contractAddr) external; /** * @dev Remove a market contract from allow-list * @param contractAddr address for REXMarket contract */ function unregisterApp (address contractAddr) external; /** * @dev Apply for a new affiliate * @param name address for customer * @param affiliateId referral ID */ function applyForAffiliate(string memory name, string memory affiliateId) external; /** * @dev Enable a affiliate and allow to refer customers * @param affiliateId referral ID */ function verifyAffiliate(string memory affiliateId) external; /** * @dev Disable affiliate and disallow to refer customers * @param affiliateId referral ID */ function disableAffiliate(string memory affiliateId) external; /** * @dev Check if an affiliate is enabled * @param affiliateId referral ID */ function isAffiliateEnabled(string memory affiliateId) external view returns (bool); /** * @dev Withdraw affiliate for caller - only allowed for a disabled affiliate */ function withdrawAffiliate() external; /** * @dev Change affiliate address (to transfer rewards) * @param newAddress address for customer */ function changeAffiliateAddress(address newAddress) external; /** * @dev Get affiliate address for customer - returns 0 if customer is organic * @param customerAddr address for customer */ function getAffiliateAddress(address customerAddr) external view returns (address); /** * @dev Perform all checks for customer and register organically or to affiliate when necessary * @param customerAddr address for new customer * @param affiliateId affiliateId of the referral */ function safeRegisterCustomer(address customerAddr, string memory affiliateId) external; }
// SPDX-License-Identifier: 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)); } }
// 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 // OpenZeppelin Contracts v4.4.1 (token/ERC777/IERC777.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC777Token standard as defined in the EIP. * * This contract uses the * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let * token holders and recipients react to token movements by using setting implementers * for the associated interfaces in said registry. See {IERC1820Registry} and * {ERC1820Implementer}. */ interface IERC777 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() external view returns (string memory); /** * @dev Returns the smallest part of the token that is not divisible. This * means all token operations (creation, movement and destruction) must have * amounts that are a multiple of this number. * * For most token contracts, this value will equal 1. */ function granularity() external view returns (uint256); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by an account (`owner`). */ function balanceOf(address owner) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * If send or receive hooks are registered for the caller and `recipient`, * the corresponding functions will be called with `data` and empty * `operatorData`. See {IERC777Sender} and {IERC777Recipient}. * * Emits a {Sent} event. * * Requirements * * - the caller must have at least `amount` tokens. * - `recipient` cannot be the zero address. * - if `recipient` is a contract, it must implement the {IERC777Recipient} * interface. */ function send( address recipient, uint256 amount, bytes calldata data ) external; /** * @dev Destroys `amount` tokens from the caller's account, reducing the * total supply. * * If a send hook is registered for the caller, the corresponding function * will be called with `data` and empty `operatorData`. See {IERC777Sender}. * * Emits a {Burned} event. * * Requirements * * - the caller must have at least `amount` tokens. */ function burn(uint256 amount, bytes calldata data) external; /** * @dev Returns true if an account is an operator of `tokenHolder`. * Operators can send and burn tokens on behalf of their owners. All * accounts are their own operator. * * See {operatorSend} and {operatorBurn}. */ function isOperatorFor(address operator, address tokenHolder) external view returns (bool); /** * @dev Make an account an operator of the caller. * * See {isOperatorFor}. * * Emits an {AuthorizedOperator} event. * * Requirements * * - `operator` cannot be calling address. */ function authorizeOperator(address operator) external; /** * @dev Revoke an account's operator status for the caller. * * See {isOperatorFor} and {defaultOperators}. * * Emits a {RevokedOperator} event. * * Requirements * * - `operator` cannot be calling address. */ function revokeOperator(address operator) external; /** * @dev Returns the list of default operators. These accounts are operators * for all token holders, even if {authorizeOperator} was never called on * them. * * This list is immutable, but individual holders may revoke these via * {revokeOperator}, in which case {isOperatorFor} will return false. */ function defaultOperators() external view returns (address[] memory); /** * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must * be an operator of `sender`. * * If send or receive hooks are registered for `sender` and `recipient`, * the corresponding functions will be called with `data` and * `operatorData`. See {IERC777Sender} and {IERC777Recipient}. * * Emits a {Sent} event. * * Requirements * * - `sender` cannot be the zero address. * - `sender` must have at least `amount` tokens. * - the caller must be an operator for `sender`. * - `recipient` cannot be the zero address. * - if `recipient` is a contract, it must implement the {IERC777Recipient} * interface. */ function operatorSend( address sender, address recipient, uint256 amount, bytes calldata data, bytes calldata operatorData ) external; /** * @dev Destroys `amount` tokens from `account`, reducing the total supply. * The caller must be an operator of `account`. * * If a send hook is registered for `account`, the corresponding function * will be called with `data` and `operatorData`. See {IERC777Sender}. * * Emits a {Burned} event. * * Requirements * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. * - the caller must be an operator for `account`. */ function operatorBurn( address account, uint256 amount, bytes calldata data, bytes calldata operatorData ) external; event Sent( address indexed operator, address indexed from, address indexed to, uint256 amount, bytes data, bytes operatorData ); event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData); event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData); event AuthorizedOperator(address indexed operator, address indexed tokenHolder); event RevokedOperator(address indexed operator, address indexed tokenHolder); }
// SPDX-License-Identifier: AGPLv3 pragma solidity >= 0.5.0; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { TokenInfo } from "./TokenInfo.sol"; /** * * @dev Interface for ERC20 token with token info * * NOTE: Using abstract contract instead of interfaces because old solidity * does not support interface inheriting other interfaces * solhint-disable-next-line no-empty-blocks * */ // solhint-disable-next-line no-empty-blocks abstract contract ERC20WithTokenInfo is IERC20, TokenInfo {}
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"contract ISuperfluid","name":"_host","type":"address"},{"internalType":"contract IConstantFlowAgreementV1","name":"_cfa","type":"address"},{"internalType":"contract IInstantDistributionAgreementV1","name":"_ida","type":"address"},{"internalType":"string","name":"_registrationKey","type":"string"},{"internalType":"contract IREXReferral","name":"_rexReferral","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"totalAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feeCollected","type":"uint256"},{"indexed":false,"internalType":"address","name":"token","type":"address"}],"name":"Distribution","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"contract ISuperToken","name":"_token","type":"address"},{"internalType":"uint128","name":"_feeRate","type":"uint128"},{"internalType":"uint256","name":"_emissionRate","type":"uint256"},{"internalType":"uint256","name":"_requestId","type":"uint256"},{"internalType":"uint128","name":"_shareScaler","type":"uint128"}],"name":"addOutputPool","outputs":[],"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":"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":"_cbdata","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":"_cbdata","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":"_superToken","type":"address"},{"internalType":"address","name":"_agreementClass","type":"address"},{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"bytes","name":"_agreementData","type":"bytes"},{"internalType":"bytes","name":"_ctx","type":"bytes"}],"name":"beforeAgreementCreated","outputs":[{"internalType":"bytes","name":"_cbdata","type":"bytes"}],"stateMutability":"view","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":"_ctx","type":"bytes"}],"name":"beforeAgreementTerminated","outputs":[{"internalType":"bytes","name":"_cbdata","type":"bytes"}],"stateMutability":"view","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":"_ctx","type":"bytes"}],"name":"beforeAgreementUpdated","outputs":[{"internalType":"bytes","name":"_cbdata","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"streamer","type":"address"},{"internalType":"contract ISuperToken","name":"token","type":"address"}],"name":"closeStream","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"ctx","type":"bytes"}],"name":"distribute","outputs":[{"internalType":"bytes","name":"newCtx","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"streamer","type":"address"},{"internalType":"contract ISuperToken","name":"token","type":"address"}],"name":"emergencyCloseStream","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISuperToken","name":"token","type":"address"}],"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":"uint32","name":"_index","type":"uint32"}],"name":"getEmissionRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_index","type":"uint32"}],"name":"getFeeRate","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_index","type":"uint32"},{"internalType":"address","name":"_streamer","type":"address"}],"name":"getIDAShares","outputs":[{"internalType":"bool","name":"_exist","type":"bool"},{"internalType":"bool","name":"_approved","type":"bool"},{"internalType":"uint128","name":"_units","type":"uint128"},{"internalType":"uint256","name":"_pendingDistribution","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getInputToken","outputs":[{"internalType":"contract ISuperToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLastDistributionAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ISuperToken","name":"token","type":"address"}],"name":"getOracleInfo","outputs":[{"components":[{"internalType":"uint256","name":"requestId","type":"uint256"},{"internalType":"uint256","name":"usdPrice","type":"uint256"},{"internalType":"uint256","name":"lastUpdatedAt","type":"uint256"}],"internalType":"struct REXMarket.OracleInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_index","type":"uint32"}],"name":"getOutputPool","outputs":[{"components":[{"internalType":"contract ISuperToken","name":"token","type":"address"},{"internalType":"uint128","name":"feeRate","type":"uint128"},{"internalType":"uint256","name":"emissionRate","type":"uint256"},{"internalType":"uint128","name":"shareScaler","type":"uint128"}],"internalType":"struct REXMarket.OutputPool","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRateTolerance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_streamer","type":"address"},{"internalType":"contract ISuperToken","name":"_token","type":"address"}],"name":"getStreamRate","outputs":[{"internalType":"int96","name":"_requesterFlowRate","type":"int96"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract ISuperToken","name":"_inputToken","type":"address"},{"internalType":"uint256","name":"_rateTolerance","type":"uint256"},{"internalType":"contract ITellor","name":"_tellor","type":"address"},{"internalType":"uint256","name":"_inputTokenRequestId","type":"uint256"},{"internalType":"uint128","name":"_affiliateFee","type":"uint128"},{"internalType":"uint128","name":"_feeRate","type":"uint128"}],"name":"initializeMarket","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_emissionRate","type":"uint256"},{"internalType":"contract ISuperToken","name":"_subsidyToken","type":"address"}],"name":"initializeSubsidies","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISuperToken","name":"_inputTokenA","type":"address"},{"internalType":"uint256","name":"_inputTokenARequestId","type":"uint256"},{"internalType":"uint128","name":"_inputTokenAShareScaler","type":"uint128"},{"internalType":"contract ISuperToken","name":"_inputTokenB","type":"address"},{"internalType":"uint256","name":"_inputTokenBRequestId","type":"uint256"},{"internalType":"uint128","name":"_inputTokenBShareScaler","type":"uint128"},{"internalType":"uint128","name":"_feeRate","type":"uint128"},{"internalType":"uint256","name":"_rateTolerance","type":"uint256"}],"name":"initializeTwoWayMarket","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isAppJailed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oracle","outputs":[{"internalType":"contract ITellor","name":"","type":"address"}],"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":[],"name":"ric","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"_index","type":"uint32"},{"internalType":"uint128","name":"_emissionRate","type":"uint128"}],"name":"setEmissionRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_index","type":"uint32"},{"internalType":"uint128","name":"_feeRate","type":"uint128"}],"name":"setFeeRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rate","type":"uint256"}],"name":"setRateTolerance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ISuperToken","name":"_token","type":"address"}],"name":"updateTokenPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"updateTokenPrices","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6080604052604d601455601580546001600160a01b0319908116731b02da8cb0d097eb8d57a175b88c7d8b47997506179091556016805490911673acc2d27400029904919ea54ffc0b18bf07c578751790553480156200005e57600080fd5b50604051620061913803806200619183398101604081905262000081916200030b565b8585858585856200009233620001d4565b600180546001600160a01b038088166001600160a01b0319928316179092556002805487841690831617905560038054868416908316179055600e805492841692909116919091179055620000e78662000224565b815160019015620001605760015460405163bd1c448b60e01b81526001600160a01b039091169063bd1c448b9062000126908490879060040162000429565b600060405180830381600087803b1580156200014157600080fd5b505af115801562000156573d6000803e3d6000fd5b50505050620001c1565b6001546040516315a722b960e31b8152600481018390526001600160a01b039091169063ad3915c890602401600060405180830381600087803b158015620001a757600080fd5b505af1158015620001bc573d6000803e3d6000fd5b505050505b50505050505050505050505050620004c4565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000546001600160a01b03163314620002845760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b6001600160a01b038116620002eb5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016200027b565b620002f681620001d4565b50565b80516200030681620004ae565b919050565b60008060008060008060c0878903121562000324578182fd5b86516200033181620004ae565b60208801519096506200034481620004ae565b60408801519095506200035781620004ae565b60608801519094506200036a81620004ae565b60808801519093506001600160401b038082111562000387578384fd5b818901915089601f8301126200039b578384fd5b815181811115620003b057620003b062000498565b604051601f8201601f19908116603f01168101908382118183101715620003db57620003db62000498565b816040528281528c6020848701011115620003f4578687fd5b6200040783602083016020880162000465565b80965050505050506200041d60a08801620002f9565b90509295509295509295565b82815260406020820152600082518060408401526200045081606085016020870162000465565b601f01601f1916919091016060019392505050565b60005b838110156200048257818101518382015260200162000468565b8381111562000492576000848401525b50505050565b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114620002f657600080fd5b615cbd80620004d46000396000f3fe608060405234801561001057600080fd5b50600436106102115760003560e01c806383688be611610125578063cdf5bd75116100ad578063e8e75cbd1161007c578063e8e75cbd146105aa578063f19a31c2146105f4578063f27be9dd14610607578063f2fde38b14610622578063fe1b09dd1461063557600080fd5b8063cdf5bd751461056b578063d86ed3e514610573578063d8ccc75b14610586578063e52e43da1461059957600080fd5b80638e1d026c116100f45780638e1d026c146104e2578063b9bb0229146104f5578063bfdb6b041461051b578063c12fc38b14610550578063c24c14e01461056357600080fd5b806383688be614610499578063884d1f40146104ac5780638d21b593146104bf5780638da5cb5b146104d157600080fd5b806353c11f99116101a85780635ce81f99116101775780635ce81f991461042d5780635f9e7d7714610440578063715018a61461045357806371a18bfb1461045b5780637dc0d1d01461046e57600080fd5b806353c11f9914610319578063587d5ff51461032c57806358a61d3d1461033f5780635c56bdc41461035257600080fd5b8063230dbd29116101e4578063230dbd29146102a357806330d9c915146102c35780633fcad964146102d657806344a8ee241461030657600080fd5b806309cd55ba146102165780630c9dfd1e1461022b57806315843a01146102785780632174661514610290575b600080fd5b610229610224366004614c7c565b61065e565b005b61023e610239366004615430565b6108a3565b60405161026f9493929190931515845291151560208401526001600160801b03166040830152606082015260800190565b60405180910390f35b610280610962565b604051901515815260200161026f565b61022961029e366004614c0c565b6109e3565b6102b66102b1366004614fb3565b610ac5565b60405161026f91906154fc565b6102b66102d1366004614f17565b610c08565b6102e96102e4366004615355565b610d48565b60408051931515845260208401929092529082015260600161026f565b61022961031436600461507a565b610f0c565b6102b6610327366004614fb3565b6110d6565b61022961033a366004614c7c565b611282565b61022961034d366004615355565b611419565b6103e2610360366004615416565b6040805160808101825260008082526020820181905291810182905260608101919091525063ffffffff166000908152600b6020908152604091829020825160808101845281546001600160a01b0316815260018201546001600160801b03908116938201939093526002820154938101939093526003015416606082015290565b60405161026f919081516001600160a01b031681526020808301516001600160801b039081169183019190915260408084015190830152606092830151169181019190915260800190565b61022961043b36600461544b565b611448565b6102b661044e366004614f17565b61149b565b61022961157e565b610229610469366004614c0c565b6115b4565b600454610481906001600160a01b031681565b6040516001600160a01b03909116815260200161026f565b6102296104a73660046150d8565b61186d565b6102b66104ba366004614f17565b611980565b6007545b60405190815260200161026f565b6000546001600160a01b0316610481565b6102296104f0366004615147565b611a28565b610508610503366004614c7c565b611e09565b604051600b9190910b815260200161026f565b61052e610529366004614c0c565b611ea0565b604080518251815260208084015190820152918101519082015260600161026f565b6102b661055e366004614e0f565b611f06565b610229612b22565b6006546104c3565b6102b6610581366004614fb3565b612b8a565b61022961059436600461536d565b612cf2565b6005546001600160a01b0316610481565b6105dc6105b8366004615416565b63ffffffff166000908152600b60205260409020600101546001600160801b031690565b6040516001600160801b03909116815260200161026f565b61022961060236600461544b565b612e5f565b61048173263026e7e53dbfdce5ae55ade22493f82892296581565b610229610630366004614c0c565b612ec2565b6104c3610643366004615416565b63ffffffff166000908152600b602052604090206002015490565b600254604051631cd43d1160e31b81526001600160a01b0383811660048301528481166024830152306044830152600092169063e6a1e8889060640160806040518083038186803b1580156106b257600080fd5b505afa1580156106c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106ea91906153b5565b5050915050806170806106fd9190615981565b6040516370a0823160e01b81526001600160a01b038581166004830152600b9290920b918416906370a082319060240160206040518083038186803b15801561074557600080fd5b505afa158015610759573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061077d9190614df7565b13156107bc5760405162461bcd60e51b815260206004820152600960248201526821636c6f7361626c6560b81b60448201526064015b60405180910390fd5b6001546002546040805160008152602081019091526001600160a01b03928316926339255d5b921690635a5999e360e11b9061080190879089903090604481016155e0565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199485161790525160e085901b9092168252610847929160040161550f565b600060405180830381600087803b15801561086157600080fd5b505af1158015610875573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261089d9190810190614e83565b50505050565b60035463ffffffff83166000818152600b6020526040808220549051635b53405160e01b81526001600160a01b0391821660048201523060248201526044810193909352848116606484015290928392839283921690635b5340519060840160806040518083038186803b15801561091a57600080fd5b505afa15801561092e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109529190614d50565b9299919850965090945092505050565b600154604051636b4f333560e01b81523060048201526000916001600160a01b031690636b4f33359060240160206040518083038186803b1580156109a657600080fd5b505afa1580156109ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109de9190614d36565b905090565b6001600160a01b0381166000908152600a602052604081205481908190610a0990610d48565b92509250925082610a4f5760405162461bcd60e51b815260206004820152601060248201526f2167657443757272656e7456616c756560801b60448201526064016107b3565b610a5b610e1042615adc565b811015610a9a5760405162461bcd60e51b815260206004820152600d60248201526c2163757272656e7456616c756560981b60448201526064016107b3565b6001600160a01b039093166000908152600a6020526040902060018101919091556002019190915550565b6060610acf612f5a565b610ad88a612f9c565b1580610aea5750610ae889612fce565b155b15610b2e5782828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929350610bfb92505050565b82828080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920182905250939450839250610b7591508a9050898e613069565b5091509150610b848c82613117565b6000610b92878901896151d4565b9050610b9c61320d565b15610bad57610baa84611f06565b93505b60006040518060800160405280856001600160a01b0316815260200183600b0b815260200184600b0b81526020018f6001600160a01b03168152509050610bf485826133d1565b9450505050505b9998505050505050505050565b6060610c12612f5a565b610c1b88612f9c565b1580610c2d5750610c2b87612fce565b155b15610c715782828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929350610d3d92505050565b6000610c7f85870187614c44565b5090506000610c8f6000836108a3565b50925050506001600160801b03811615610cdf5760405162461bcd60e51b8152602060048201526011602482015270416c72656164792073747265616d696e6760781b60448201526064016107b3565b610cea6001836108a3565b50925050506001600160801b03811615610d3a5760405162461bcd60e51b8152602060048201526011602482015270416c72656164792073747265616d696e6760781b60448201526064016107b3565b50505b979650505050505050565b600480546040516311bbb87160e21b81529182018390526000918291829182916001600160a01b0316906346eee1c49060240160206040518083038186803b158015610d9357600080fd5b505afa158015610da7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dcb9190614df7565b6004549091506001600160a01b03166377fbb66386610deb600185615adc565b6040516001600160e01b031960e085901b1681526004810192909252602482015260440160206040518083038186803b158015610e2757600080fd5b505afa158015610e3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e5f9190614df7565b600480546040516393fa491560e01b81529294506001600160a01b0316916393fa491591610e9a918991879101918252602082015260400190565b60206040518083038186803b158015610eb257600080fd5b505afa158015610ec6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eea9190614df7565b92508215610efc576001935050610f05565b60008093509350505b9193909250565b6000546001600160a01b03163314610f365760405162461bcd60e51b81526004016107b3906156ee565b600d54600460ff90911610610f7e5760405162461bcd60e51b815260206004820152600e60248201526d746f6f206d616e7920706f6f6c7360901b60448201526064016107b3565b604080516080810182526001600160a01b038088168083526001600160801b0380891660208086019182528587018a815288841660608801908152600d805460ff9081166000908152600b86528b81208b5181549b166001600160a01b0319909b169a909a178a55955160018a0180549189166001600160801b0319928316179055935160028a01559151600390980180549890961697909216969096179093558254938252600c905294909420805463ffffffff19169183169190911790559154909161104d9116876135dc565b600d805460ff1690600061106083615b66565b825460ff9182166101009390930a92830291909202199091161790555060408051606081018252848152600060208083018281528385018381526001600160a01b038c168452600a909252939091208251815592516001840155516002909201919091556110cd876109e3565b50505050505050565b60606110e0612f5a565b6110e98a612f9c565b15806110fb57506110f989612fce565b155b1561113f5782828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929350610bfb92505050565b82828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509394506111849250505087890189614c44565b50905060008061119687890189615391565b9150915060006040518060800160405280856001600160a01b0316815260200183600b0b81526020016000600b0b81526020018f6001600160a01b031681525090506111e285826133d1565b6040516323b872dd60e01b81523060048201526001600160a01b03868116602483015260448201869052919650908f16906323b872dd90606401602060405180830381600087803b15801561123657600080fd5b505af1925050508015611266575060408051601f3d908101601f1916820190925261126391810190614d36565b60015b61126f57611271565b505b505050509998505050505050505050565b600154604051636b4f333560e01b81523060048201526001600160a01b0390911690636b4f33359060240160206040518083038186803b1580156112c557600080fd5b505afa1580156112d9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112fd9190614d36565b6113335760405162461bcd60e51b8152602060048201526007602482015266085a985a5b195960ca1b60448201526064016107b3565b6001546002546040805160008152602081019091526001600160a01b03928316926339255d5b921690635a5999e360e11b9061137890869088903090604481016155e0565b60408051601f198184030181529181526020820180516001600160e01b03166001600160e01b03199485161790525160e085901b90921682526113be929160040161550f565b600060405180830381600087803b1580156113d857600080fd5b505af11580156113ec573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526114149190810190614e83565b505050565b6000546001600160a01b031633146114435760405162461bcd60e51b81526004016107b3906156ee565b600755565b6000546001600160a01b031633146114725760405162461bcd60e51b81526004016107b3906156ee565b63ffffffff9091166000908152600b602052604090206001600160801b03909116600290910155565b60606114a5612f5a565b6114ae88612f9c565b15806114c057506114be87612fce565b155b156115045782828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929350610d3d92505050565b600080600061151488888d613069565b925092509250600061153d82846bffffffffffffffffffffffff166115388f613673565b6136a7565b90508083600b0b60405160200161155e929190918252602082015260400190565b604051602081830303815290604052945050505050979650505050505050565b6000546001600160a01b031633146115a85760405162461bcd60e51b81526004016107b3906156ee565b6115b260006136d4565b565b6000546001600160a01b031633146115de5760405162461bcd60e51b81526004016107b3906156ee565b60025460405163e8e7e2d160e01b81526001600160a01b0383811660048301523060248301529091169063e8e7e2d19060440160206040518083038186803b15801561162957600080fd5b505afa15801561163d573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061166191906151f0565b600b0b156116a25760405162461bcd60e51b815260206004820152600e60248201526d217a65726f53747265616d65727360901b60448201526064016107b3565b600154604051636b4f333560e01b81523060048201526001600160a01b0390911690636b4f33359060240160206040518083038186803b1580156116e557600080fd5b505afa1580156116f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061171d9190614d36565b6117535760405162461bcd60e51b8152602060048201526007602482015266085a985a5b195960ca1b60448201526064016107b3565b806001600160a01b031663a9059cbb6117746000546001600160a01b031690565b6040516370a0823160e01b81523060048201526001600160a01b038516906370a082319060240160206040518083038186803b1580156117b357600080fd5b505afa1580156117c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117eb9190614df7565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401602060405180830381600087803b15801561183157600080fd5b505af1158015611845573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118699190614d36565b5050565b6000546001600160a01b031633146118975760405162461bcd60e51b81526004016107b3906156ee565b6005546001600160a01b0316156118e65760405162461bcd60e51b8152602060048201526013602482015272105b1c9958591e481a5b9a5d1a585b1a5e9959606a1b60448201526064016107b3565b600580546001600160a01b038089166001600160a01b0319928316811790935560078890556001600160801b03848116908616600160801b026001600160801b0319161760085560048054918816919092161790556040805160608101825285815260006020808301828152838501838152958352600a90915292902081518155915160018301559151600291909101556110cd876109e3565b606061198a612f5a565b61199388612f9c565b15806119a557506119a387612fce565b155b156119e95782828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929350610d3d92505050565b60006119f686868b613069565b5060408051600b83900b6020820152919350019050604051602081830303815290604052915050979650505050505050565b6000546001600160a01b03163314611a525760405162461bcd60e51b81526004016107b3906156ee565b600054600160a81b900460ff16611a7657600054600160a01b900460ff1615611a7a565b303b155b611add5760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084016107b3565b600054600160a81b900460ff16158015611b07576000805461ffff60a01b191661010160a01b1790555b600f80546001600160a01b03199081166001600160a01b038c81169182179093556010805483168a851617905560058054831690911790556007849055601654600480549190931691161790556001600160801b03838116613d0960851b17600855620f424090881610801590611b8a5750620f4240846001600160801b031610155b611bc35760405162461bcd60e51b815260206004820152600a602482015269217363616c6561626c6560b01b60448201526064016107b3565b600f54611bdd906001600160a01b03168460008b8b610f0c565b601054611bf7906001600160a01b03168460008888610f0c565b600f80546001600160a01b039081166000908152600c60209081526040808320805463ffffffff19908116909155601054851684528184208054909116600117905593548451631dce337960e31b81529451929493169263ee719bc89260048083019392829003018186803b158015611c6f57600080fd5b505afa158015611c83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ca79190614c28565b90506000601060009054906101000a90046001600160a01b03166001600160a01b031663ee719bc86040518163ffffffff1660e01b815260040160206040518083038186803b158015611cf957600080fd5b505afa158015611d0d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d319190614c28565b90506001600160a01b038216611d5457600f546001600160a01b03169150611d70565b600f54611d70906001600160a01b038481169116600019613724565b6001600160a01b038116611d9057506010546001600160a01b0316611dac565b601054611dac906001600160a01b038381169116600019613724565b601554611dc8906001600160a01b038481169116600019613724565b601554611de4906001600160a01b038381169116600019613724565b5050426006558015611dfe576000805460ff60a81b191690555b505050505050505050565b600254604051631cd43d1160e31b81526001600160a01b0383811660048301528481166024830152306044830152600092169063e6a1e8889060640160806040518083038186803b158015611e5d57600080fd5b505afa158015611e71573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e9591906153b5565b509095945050505050565b611ec460405180606001604052806000815260200160008152602001600081525090565b506001600160a01b03166000908152600a6020908152604091829020825160608101845281548152600182015492810192909252600201549181019190915290565b80611f13610e1042615adc565b7fdf7de25b7f1fd6d0b5205f0e18f1f35bd7b8d84cce336588d184533ce43a6f76546001600160a01b03166000908152600a60205260409020600201541015611f8f5760405162461bcd60e51b815260206004820152600e60248201526d2163757272656e7456616c75654160901b60448201526064016107b3565b611f9b610e1042615adc565b7f72c6bfb7988af3a1efa6568f02a999bc52252641c659d85961ca3d372b57d5cf546001600160a01b03166000908152600a602052604090206002015410156120175760405162461bcd60e51b815260206004820152600e60248201526d10b1bab93932b73a2b30b63ab2a160911b60448201526064016107b3565b600f546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561205b57600080fd5b505afa15801561206f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120939190614df7565b6010546040516370a0823160e01b81523060048201529192506000916001600160a01b03909116906370a082319060240160206040518083038186803b1580156120dc57600080fd5b505afa1580156120f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121149190614df7565b600f546001600160a01b039081166000908152600a602052604080822060019081015460105490941683529082200154929350916121529084615a46565b61215c919061587f565b9050828110156121a2576121708184615adc565b600f5460105491925061219c916001600160a01b0391821691168361219742610e10615841565b613807565b5061221a565b6010546001600160a01b039081166000908152600a6020526040808220600190810154600f549094168352912001546121db9085615a46565b6121e5919061587f565b90506121f18183615adc565b601054600f54919250612218916001600160a01b0391821691168361219742610e10615841565b505b600f546040516370a0823160e01b81523060048201526001600160a01b03909116906370a082319060240160206040518083038186803b15801561225d57600080fd5b505afa158015612271573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122959190614df7565b6010546040516370a0823160e01b81523060048201529194506001600160a01b0316906370a082319060240160206040518083038186803b1580156122d957600080fd5b505afa1580156122ed573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123119190614df7565b91508215801561231f575081155b1561232c57505050919050565b6003546000808052600b6020527fdf7de25b7f1fd6d0b5205f0e18f1f35bd7b8d84cce336588d184533ce43a6f76546040516323fc23f360e01b815291928392839283926001600160a01b03908116926323fc23f39261239492169030908690600401615614565b60806040518083038186803b1580156123ac57600080fd5b505afa1580156123c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123e49190614d9c565b93509350505060008711801561240c575060006124018284615816565b6001600160801b0316115b1561272157600354600f54604051632266eabb60e21b81526001600160a01b03918216600482015230602482015260006044820152606481018a905291169063899baaec90608401604080518083038186803b15801561246b57600080fd5b505afa15801561247f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124a391906153f2565b50600f546040516370a0823160e01b815230600482015291985088916001600160a01b03909116906370a082319060240160206040518083038186803b1580156124ec57600080fd5b505afa158015612500573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125249190614df7565b101561255c5760405162461bcd60e51b8152602060048201526007602482015266042cadcdeeaced60cb1b60448201526064016107b3565b600f546125779060009089906001600160a01b03168b613f30565b600f5460408051868152602081018890526001600160a01b0390921690820152909850600080516020615c688339815191529060600160405180910390a16002600052600b6020527fa50eece07c7db1631545c0069bd8f5f54d5935e215d59097edf258a44ba91636546011546125ee9042615adc565b6125f89190615a46565b6002600052600b602052600080516020615c28833981519152546040516370a0823160e01b81523060048201529194506001600160a01b0316906370a082319060240160206040518083038186803b15801561265357600080fd5b505afa158015612667573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061268b9190614df7565b83101561271c5760026000819052600b602052600080516020615c28833981519152546126c4919085906001600160a01b03168b613f30565b60026000908152600b6020908152600080516020615c288339815191525460408051888152928301939093526001600160a01b0316818301529051919950600080516020615c68833981519152919081900360600190a15b426011555b60035460016000819052600b6020527f72c6bfb7988af3a1efa6568f02a999bc52252641c659d85961ca3d372b57d5cf546040516323fc23f360e01b81526001600160a01b03938416936323fc23f3936127849390911691309190600401615614565b60806040518083038186803b15801561279c57600080fd5b505afa1580156127b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127d49190614d9c565b9094509250505085158015906127fc575060006127f18284615816565b6001600160801b0316115b15612b1157600354601054604051632266eabb60e21b81526001600160a01b039182166004820152306024820152600160448201526064810189905291169063899baaec90608401604080518083038186803b15801561285b57600080fd5b505afa15801561286f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061289391906153f2565b506010546040516370a0823160e01b815230600482015291975087916001600160a01b03909116906370a082319060240160206040518083038186803b1580156128dc57600080fd5b505afa1580156128f0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129149190614df7565b101561294c5760405162461bcd60e51b8152602060048201526007602482015266042cadcdeeaced60cb1b60448201526064016107b3565b6010546129679060019088906001600160a01b03168b613f30565b60105460408051868152602081018890526001600160a01b0390921690820152909850600080516020615c688339815191529060600160405180910390a16003600052600b6020527f64c15cc42be7899b001f818cf4433057002112c418d1d3a67cd5cb453051d340546012546129de9042615adc565b6129e89190615a46565b6003600052600b602052600080516020615c48833981519152546040516370a0823160e01b81523060048201529194506001600160a01b0316906370a082319060240160206040518083038186803b158015612a4357600080fd5b505afa158015612a57573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a7b9190614df7565b831015612b0c5760036000819052600b602052600080516020615c4883398151915254612ab4919085906001600160a01b03168b613f30565b60036000908152600b6020908152600080516020615c488339815191525460408051888152928301939093526001600160a01b0316818301529051919950600080516020615c68833981519152919081900360600190a15b426012555b505042600655509395945050505050565b600554612b37906001600160a01b03166109e3565b60005b600d5460ff1663ffffffff82161015612b875763ffffffff81166000908152600b6020526040902054612b75906001600160a01b03166109e3565b80612b7f81615b42565b915050612b3a565b50565b6060612b94612f5a565b612b9d8a612f9c565b1580612baf5750612bad89612fce565b155b15612bf35782828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929350610bfb92505050565b82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929350612c36925061320d915050565b15612c4757612c4481611f06565b90505b600080612c5589898e613069565b5091509150612c648c82613117565b612ca585858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250869250614127915050565b604080516080810182526001600160a01b03808516825260006020830152600b84900b92820192909252908d166060820152612ce184826133d1565b9d9c50505050505050505050505050565b6000546001600160a01b03163314612d1c5760405162461bcd60e51b81526004016107b3906156ee565b601380546001600160a01b0319166001600160a01b03838116919091179091556002600052600b602052600080516020615c288339815191525416158015612d8457506003600052600b602052600080516020615c48833981519152546001600160a01b0316155b612dc65760405162461bcd60e51b8152602060048201526013602482015272185b1c9958591e481a5b9a5d1a585b1a5e9959606a1b60448201526064016107b3565b60016000908152600b6020527f72c6bfb7988af3a1efa6568f02a999bc52252641c659d85961ca3d372b57d5d254612e0d9183918590604d906001600160801b0316610f0c565b6000808052600b6020527fdf7de25b7f1fd6d0b5205f0e18f1f35bd7b8d84cce336588d184533ce43a6f7954612e529183918590604d906001600160801b0316610f0c565b5050426011819055601255565b6000546001600160a01b03163314612e895760405162461bcd60e51b81526004016107b3906156ee565b63ffffffff919091166000908152600b6020526040902060010180546001600160801b0319166001600160801b03909216919091179055565b6000546001600160a01b03163314612eec5760405162461bcd60e51b81526004016107b3906156ee565b6001600160a01b038116612f515760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016107b3565b612b87816136d4565b6001546001600160a01b031633146115b25760405162461bcd60e51b8152602060048201526005602482015264085a1bdcdd60da1b60448201526064016107b3565b600f546000906001600160a01b0383811691161480612fc857506010546001600160a01b038381169116145b92915050565b60007fa9214cc96615e0085d3bb077758db69497dc2dce3b2b1e97bc93c3d18d83efd3826001600160a01b0316637730599e6040518163ffffffff1660e01b815260040160206040518083038186803b15801561302a57600080fd5b505afa15801561303e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130629190614df7565b1492915050565b6000808061307985870187614c44565b50600254604051631cd43d1160e31b81526001600160a01b038781166004830152808416602483015230604483015292955091169063e6a1e8889060640160806040518083038186803b1580156130cf57600080fd5b505afa1580156130e3573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061310791906153b5565b5094989097509095509350505050565b6001600160a01b0382166000908152600c602052604090205463ffffffff166131cd576001600052600b6020527f72c6bfb7988af3a1efa6568f02a999bc52252641c659d85961ca3d372b57d5d25461317b906001600160801b03166103e8615a17565b81600b0b6131899190615b86565b6001600160801b0316156118695760405162461bcd60e51b815260206004820152600b60248201526a6e6f745363616c61626c6560a81b60448201526064016107b3565b60008052600b6020527fdf7de25b7f1fd6d0b5205f0e18f1f35bd7b8d84cce336588d184533ce43a6f795461317b906001600160801b03166103e8615a17565b6003546000808052600b6020527fdf7de25b7f1fd6d0b5205f0e18f1f35bd7b8d84cce336588d184533ce43a6f76546040516323fc23f360e01b81529192839283926001600160a01b03928316926323fc23f392613275929091169030908690600401615614565b60806040518083038186803b15801561328d57600080fd5b505afa1580156132a1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132c59190614d9c565b935093505050600081836132d99190615816565b6001600160801b031611156133c85760035460016000819052600b6020527f72c6bfb7988af3a1efa6568f02a999bc52252641c659d85961ca3d372b57d5cf546040516323fc23f360e01b81526001600160a01b03938416936323fc23f39361334b9390911691309190600401615614565b60806040518083038186803b15801561336357600080fd5b505afa158015613377573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061339b9190614d9c565b9094509250600091506133b090508284615816565b6001600160801b031611156133c85760019250505090565b60009250505090565b6060818101516001600160a01b03166000908152600c6020526040812054819063ffffffff166134175750506010546001600160a01b031660608301526001600361342f565b5050600f546001600160a01b03166060830152600060025b600080600061343d87614311565b895163ffffffff89166000818152600b60205260409020548d9b50949750929550909350613479928992919087906001600160a01b03166147db565b875160135491975061349f91889163ffffffff88169187906001600160a01b03166147db565b95506134e4868663ffffffff166134be6000546001600160a01b031690565b63ffffffff89166000908152600b602052604090205486906001600160a01b03166147db565b600e548851604051630e9ebfbf60e01b81526001600160a01b039182166004820152929850600092911690630e9ebfbf9060240160206040518083038186803b15801561353057600080fd5b505afa158015613544573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135689190614c28565b90506001600160a01b038116156135d05763ffffffff86166000818152600b60205260409020546135a7918991849086906001600160a01b03166147db565b6013549097506135cd90889063ffffffff881690849086906001600160a01b03166147db565b96505b50505050505092915050565b6001546003546040805160008152602081019091526001600160a01b03928316926339255d5b921690636bc3c20560e11b9061361f90869088906044810161567f565b60408051601f19818403018152918152602080830180516001600160e01b03166001600160e01b03199586161790528151600081529081019182905260e086901b90931690526113be929160248101615556565b6001600160a01b0381166000908152600c602052604081205463ffffffff161561369f57601154612fc8565b505060125490565b60008184116136b657816136b8565b835b6136c29042615adc565b6136cc9084615a46565b949350505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b604051636eb1769f60e11b81523060048201526001600160a01b038381166024830152600091839186169063dd62ed3e9060440160206040518083038186803b15801561377057600080fd5b505afa158015613784573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137a89190614df7565b6137b29190615841565b604080516001600160a01b038616602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663095ea7b360e01b17905290915061089d9085906148db565b60008060006060600080896001600160a01b031663ee719bc86040518163ffffffff1660e01b815260040160206040518083038186803b15801561384a57600080fd5b505afa15801561385e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138829190614c28565b9450886001600160a01b031663ee719bc86040518163ffffffff1660e01b815260040160206040518083038186803b1580156138bd57600080fd5b505afa1580156138d1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138f59190614c28565b93506001600160a01b03851661390d57899450613a72565b6040516308de640f60e11b8152600481018990526001600160a01b038b16906311bcc81e90602401600060405180830381600087803b15801561394f57600080fd5b505af1158015613963573d6000803e3d6000fd5b50505050846001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b1580156139a057600080fd5b505afa1580156139b4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139d89190615476565b6139e3906012615af3565b6139ee90600a6158d6565b6040516370a0823160e01b81523060048201526001600160a01b038716906370a082319060240160206040518083038186803b158015613a2d57600080fd5b505afa158015613a41573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a659190614df7565b613a6f9190615a46565b97505b6001600160a01b038416613a84578893505b6001600160a01b03808a166000908152600a6020526040808220600190810154938e16835291200154613ab7908a615a46565b613ac1919061587f565b600754909250620f424090613ad69082615adc565b613ae09084615a46565b613aea919061587f565b9150670de0b6b3a7640000846001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015613b2e57600080fd5b505afa158015613b42573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b669190615476565b613b7190600a6158d6565b613b7b9084615a46565b613b85919061587f565b9150846001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015613bc057600080fd5b505afa158015613bd4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613bf89190615476565b613c03906012615af3565b613c0e90600a6158d6565b613c18908961587f565b604080516002808252606082018352929a5091906020830190803683370190505092508483600081518110613c5d57634e487b7160e01b600052603260045260246000fd5b60200260200101906001600160a01b031690816001600160a01b0316815250508383600181518110613c9f57634e487b7160e01b600052603260045260246000fd5b6001600160a01b0392831660209182029290920101526015546040516338ed173960e01b81529116906338ed173990613ce4908b908690889030908e90600401615723565b600060405180830381600087803b158015613cfe57600080fd5b505af1158015613d12573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052613d3a9190810190614c8e565b506040516370a0823160e01b81523060048201526001600160a01b038516906370a082319060240160206040518083038186803b158015613d7a57600080fd5b505afa158015613d8e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613db29190614df7565b9050836001600160a01b0316896001600160a01b031614610bfb57886001600160a01b03166345977d03856001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b158015613e1557600080fd5b505afa158015613e29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e4d9190615476565b613e58906012615af3565b613e6390600a6158d6565b6040516370a0823160e01b81523060048201526001600160a01b038816906370a082319060240160206040518083038186803b158015613ea257600080fd5b505afa158015613eb6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613eda9190614df7565b613ee49190615a46565b6040518263ffffffff1660e01b8152600401613f0291815260200190565b600060405180830381600087803b158015613f1c57600080fd5b505af1158015611271573d6000803e3d6000fd5b8051819061402d576001546003546040805160008152602081019091526001600160a01b03928316926339255d5b921690635cb398e160e11b90613f7d9088908b908b90604481016156af565b60408051601f19818403018152918152602080830180516001600160e01b03166001600160e01b03199586161790528151600081529081019182905260e086901b9093169052613fd1929160248101615556565b600060405180830381600087803b158015613feb57600080fd5b505af1158015613fff573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526140279190810190614e83565b506136cc565b6001546003546040805160008152602081019091526001600160a01b0392831692634329d293921690635cb398e160e11b906140729088908b908b90604481016156af565b60408051601f19818403018152918152602080830180516001600160e01b03166001600160e01b03199586161790528151600081529081019182905260e086901b90931690526140c792918660248201615596565b600060405180830381600087803b1580156140e157600080fd5b505af11580156140f5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261411d9190810190614eb6565b5095945050505050565b600e5460405163bfdd83f360e01b81526001600160a01b0383811660048301529091169063bfdd83f39060240160206040518083038186803b15801561416c57600080fd5b505afa158015614180573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141a49190614df7565b156141e05760405162461bcd60e51b815260206004820152600c60248201526b6e6f416666696c696174657360a01b60448201526064016107b3565b600154604051631fb6491d60e11b81526000916001600160a01b031690633f6c923a906142119086906004016154fc565b60006040518083038186803b15801561422957600080fd5b505afa15801561423d573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526142659190810190615252565b9050606060008260a00151511115614296578160a0015180602001905181019061428f919061520c565b90506142a7565b506040805160208101909152600081525b600e54604051634a2f43a560e01b81526001600160a01b0390911690634a2f43a5906142d990869085906004016154d8565b600060405180830381600087803b1580156142f357600080fd5b505af1158015614307573d6000803e3d6000fd5b5050505050505050565b60608101516001600160a01b03166000908152600c60205260408120548190819061434e9063ffffffff166102396000546001600160a01b031690565b5060608701516001600160a01b03166000908152600c602090815260408083205463ffffffff168352600b90915290206003015490945061439b92506001600160801b0316905083615a17565b600e548551604051630e9ebfbf60e01b81526001600160a01b039182166004820152929450600092911690630e9ebfbf9060240160206040518083038186803b1580156143e757600080fd5b505afa1580156143fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061441f9190614c28565b90506001600160a01b038116156144ad5760608501516001600160a01b03166000908152600c602052604090205461445d9063ffffffff16826108a3565b5060608801516001600160a01b03166000908152600c602090815260408083205463ffffffff168352600b9091529020600301549094506144aa92506001600160801b0316905083615a17565b91505b6000856020015186604001516144c39190615a65565b905060008082600b0b131561458f57600854620f4240906144f1906001600160801b0316600b85900b615a46565b6144fb919061587f565b90506001600160a01b0383161561457e57600854620f42409061452e90600160801b90046001600160801b031683615a17565b6145389190615859565b6145429085615816565b600854909450620f42409061456790600160801b90046001600160801b031683615a17565b6145719190615859565b61457b9082615ab4565b90505b6145888186615816565b94506146bd565b61459b82600019615981565b600854909250620f4240906145bd906001600160801b0316600b85900b615a46565b6145c7919061587f565b90506001600160a01b0383161561468f576008546001600160801b0380861691620f4240916145fe91600160801b90041684615a17565b6146089190615859565b6001600160801b03161161464757600854620f42409061463890600160801b90046001600160801b031683615a17565b6146429190615859565b614649565b835b6146539085615ab4565b600854909450620f42409061467890600160801b90046001600160801b031683615a17565b6146829190615859565b61468c9082615ab4565b90505b846001600160801b0316816001600160801b0316116146ae57806146b0565b845b6146ba9086615ab4565b94505b600854620f4240906146d8906001600160801b031682615ab4565b8860400151600b0b6146ea9190615a17565b6146f49190615859565b60608801516001600160a01b03166000908152600c602090815260408083205463ffffffff168352600b90915290206003015490965061473d906001600160801b031685615859565b60608801516001600160a01b03166000908152600c602090815260408083205463ffffffff168352600b909152902060030154909450614786906001600160801b031686615859565b60608801516001600160a01b03166000908152600c602090815260408083205463ffffffff168352600b9091529020600301549095506147cf906001600160801b031687615859565b95505050509193909250565b60015460035460408051600081526020810190915287926001600160a01b0390811692634329d29392911690630465a56b60e31b906148259087908b908b908b906044810161563d565b60408051601f19818403018152918152602080830180516001600160e01b03166001600160e01b03199586161790528151600081529081019182905260e086901b909316905261487a92918660248201615596565b600060405180830381600087803b15801561489457600080fd5b505af11580156148a8573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526148d09190810190614eb6565b509695505050505050565b6000614930826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166149ad9092919063ffffffff16565b805190915015611414578080602001905181019061494e9190614d36565b6114145760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b60648201526084016107b3565b60606136cc84846000856149c3565b9392505050565b606082471015614a245760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b60648201526084016107b3565b843b614a725760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000060448201526064016107b3565b600080866001600160a01b03168587604051614a8e91906154bc565b60006040518083038185875af1925050503d8060008114614acb576040519150601f19603f3d011682016040523d82523d6000602084013e614ad0565b606091505b5091509150610d3d82828660608315614aea5750816149bc565b825115614afa5782518084602001fd5b8160405162461bcd60e51b81526004016107b391906154fc565b6000614b27614b22846157ee565b6157bd565b9050828152838383011115614b3b57600080fd5b6149bc836020830184615b16565b8051614b5481615bee565b919050565b80518015158114614b5457600080fd5b80516001600160e01b031981168114614b5457600080fd5b60008083601f840112614b92578182fd5b50813567ffffffffffffffff811115614ba9578182fd5b602083019150836020828501011115614bc157600080fd5b9250929050565b600082601f830112614bd8578081fd5b6149bc83835160208501614b14565b803563ffffffff81168114614b5457600080fd5b805160ff81168114614b5457600080fd5b600060208284031215614c1d578081fd5b81356149bc81615bee565b600060208284031215614c39578081fd5b81516149bc81615bee565b60008060408385031215614c56578081fd5b8235614c6181615bee565b91506020830135614c7181615bee565b809150509250929050565b60008060408385031215614c56578182fd5b60006020808385031215614ca0578182fd5b825167ffffffffffffffff80821115614cb7578384fd5b818501915085601f830112614cca578384fd5b815181811115614cdc57614cdc615bd8565b8060051b9150614ced8483016157bd565b8181528481019084860184860187018a1015614d07578788fd5b8795505b83861015614d29578051835260019590950194918601918601614d0b565b5098975050505050505050565b600060208284031215614d47578081fd5b6149bc82614b59565b60008060008060808587031215614d65578182fd5b614d6e85614b59565b9350614d7c60208601614b59565b92506040850151614d8c81615c12565b6060959095015193969295505050565b60008060008060808587031215614db1578182fd5b614dba85614b59565b93506020850151614dca81615c12565b6040860151909350614ddb81615c12565b6060860151909250614dec81615c12565b939692955090935050565b600060208284031215614e08578081fd5b5051919050565b600060208284031215614e20578081fd5b813567ffffffffffffffff811115614e36578182fd5b8201601f81018413614e46578182fd5b8035614e54614b22826157ee565b818152856020838501011115614e68578384fd5b81602084016020830137908101602001929092525092915050565b600060208284031215614e94578081fd5b815167ffffffffffffffff811115614eaa578182fd5b6136cc84828501614bc8565b60008060408385031215614ec8578182fd5b825167ffffffffffffffff80821115614edf578384fd5b614eeb86838701614bc8565b93506020850151915080821115614f00578283fd5b50614f0d85828601614bc8565b9150509250929050565b600080600080600080600060a0888a031215614f31578485fd5b8735614f3c81615bee565b96506020880135614f4c81615bee565b955060408801359450606088013567ffffffffffffffff80821115614f6f578485fd5b614f7b8b838c01614b81565b909650945060808a0135915080821115614f93578384fd5b50614fa08a828b01614b81565b989b979a50959850939692959293505050565b600080600080600080600080600060c08a8c031215614fd0578283fd5b8935614fdb81615bee565b985060208a0135614feb81615bee565b975060408a0135965060608a013567ffffffffffffffff8082111561500e578485fd5b61501a8d838e01614b81565b909850965060808c0135915080821115615032578485fd5b61503e8d838e01614b81565b909650945060a08c0135915080821115615056578384fd5b506150638c828d01614b81565b915080935050809150509295985092959850929598565b600080600080600060a08688031215615091578283fd5b853561509c81615bee565b945060208601356150ac81615c12565b9350604086013592506060860135915060808601356150ca81615c12565b809150509295509295909350565b60008060008060008060c087890312156150f0578384fd5b86356150fb81615bee565b955060208701359450604087013561511281615bee565b935060608701359250608087013561512981615c12565b915060a087013561513981615c12565b809150509295509295509295565b600080600080600080600080610100898b031215615163578182fd5b883561516e81615bee565b975060208901359650604089013561518581615c12565b9550606089013561519581615bee565b94506080890135935060a08901356151ac81615c12565b925060c08901356151bc81615c12565b8092505060e089013590509295985092959890939650565b6000602082840312156151e5578081fd5b81356149bc81615c03565b600060208284031215615201578081fd5b81516149bc81615c03565b60006020828403121561521d578081fd5b815167ffffffffffffffff811115615233578182fd5b8201601f81018413615243578182fd5b6136cc84825160208401614b14565b600060208284031215615263578081fd5b815167ffffffffffffffff8082111561527a578283fd5b90830190610160828603121561528e578283fd5b615296615793565b61529f83614bfb565b81526152ad60208401614bfb565b6020820152604083015160408201526152c860608401614b49565b60608201526152d960808401614b69565b608082015260a0830151828111156152ef578485fd5b6152fb87828601614bc8565b60a08301525060c083015160c082015260e083015160e0820152610100915081830151828201526101209150615332828401614b49565b828201526101409150615346828401614b49565b91810191909152949350505050565b600060208284031215615366578081fd5b5035919050565b6000806040838503121561537f578182fd5b823591506020830135614c7181615bee565b600080604083850312156153a3578182fd5b823591506020830135614c7181615c03565b600080600080608085870312156153ca578182fd5b8451935060208501516153dc81615c03565b6040860151606090960151949790965092505050565b60008060408385031215615404578182fd5b825191506020830151614c7181615c12565b600060208284031215615427578081fd5b6149bc82614be7565b60008060408385031215615442578182fd5b614c6183614be7565b6000806040838503121561545d578182fd5b61546683614be7565b91506020830135614c7181615c12565b600060208284031215615487578081fd5b6149bc82614bfb565b600081518084526154a8816020860160208601615b16565b601f01601f19169290920160200192915050565b600082516154ce818460208701615b16565b9190910192915050565b6001600160a01b03831681526040602082018190526000906136cc90830184615490565b6020815260006149bc6020830184615490565b6001600160a01b038316815260606020820181905260009061553390830184615490565b8281036040938401526002815261060f60f31b6020820152919091019392505050565b6001600160a01b038416815260606020820181905260009061557a90830185615490565b828103604084015261558c8185615490565b9695505050505050565b6001600160a01b03851681526080602082018190526000906155ba90830186615490565b82810360408401526155cc8186615490565b90508281036060840152610d3d8185615490565b6001600160a01b03858116825284811660208301528316604082015260806060820181905260009061558c90830184615490565b6001600160a01b03938416815291909216602082015263ffffffff909116604082015260600190565b6001600160a01b03868116825260208201869052841660408201526001600160801b038316606082015260a060808201819052600090610d3d90830184615490565b60018060a01b03841681528260208201526060604082015260006156a66060830184615490565b95945050505050565b6001600160a01b038516815263ffffffff841660208201526001600160801b038316604082015260806060820181905260009061558c90830184615490565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b600060a082018783526020878185015260a0604085015281875180845260c0860191508289019350845b818110156157725784516001600160a01b03168352938301939183019160010161574d565b50506001600160a01b03969096166060850152505050608001529392505050565b604051610160810167ffffffffffffffff811182821017156157b7576157b7615bd8565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156157e6576157e6615bd8565b604052919050565b600067ffffffffffffffff82111561580857615808615bd8565b50601f01601f191660200190565b60006001600160801b0380831681851680830382111561583857615838615bac565b01949350505050565b6000821982111561585457615854615bac565b500190565b60006001600160801b038084168061587357615873615bc2565b92169190910492915050565b60008261588e5761588e615bc2565b500490565b600181815b808511156158ce5781600019048211156158b4576158b4615bac565b808516156158c157918102915b93841c9390800290615898565b509250929050565b60006149bc60ff8416836000826158ef57506001612fc8565b816158fc57506000612fc8565b8160018114615912576002811461591c57615938565b6001915050612fc8565b60ff84111561592d5761592d615bac565b50506001821b612fc8565b5060208310610133831016604e8410600b841016171561595b575081810a612fc8565b6159658383615893565b806000190482111561597957615979615bac565b029392505050565b600081600b0b83600b0b60016001605f1b03838213848413838304851182821616156159af576159af615bac565b6b7fffffffffffffffffffffff19868512828116878305871216156159d6576159d6615bac565b8787129250858205871284841616156159f1576159f1615bac565b85850587128184161615615a0757615a07615bac565b5050509290910295945050505050565b60006001600160801b0380831681851681830481118215151615615a3d57615a3d615bac565b02949350505050565b6000816000190483118215151615615a6057615a60615bac565b500290565b600081600b0b83600b0b8281128160016001605f1b031901831281151615615a8f57615a8f615bac565b8160016001605f1b03018313811615615aaa57615aaa615bac565b5090039392505050565b60006001600160801b0383811690831681811015615ad457615ad4615bac565b039392505050565b600082821015615aee57615aee615bac565b500390565b600060ff821660ff841680821015615b0d57615b0d615bac565b90039392505050565b60005b83811015615b31578181015183820152602001615b19565b8381111561089d5750506000910152565b600063ffffffff80831681811415615b5c57615b5c615bac565b6001019392505050565b600060ff821660ff811415615b7d57615b7d615bac565b60010192915050565b60006001600160801b0380841680615ba057615ba0615bc2565b92169190910692915050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114612b8757600080fd5b80600b0b8114612b8757600080fd5b6001600160801b0381168114612b8757600080fdfea50eece07c7db1631545c0069bd8f5f54d5935e215d59097edf258a44ba9163464c15cc42be7899b001f818cf4433057002112c418d1d3a67cd5cb453051d33eed4b43d1c43fa6de2432cc50d2bbc8db51d9ce0d2095d0a5cfac618764e9fe58a264697066735822122051060ed3e9d0de82add488f1bc6734d494f7d179c70090a9875fd9298488003c64736f6c634300080400330000000000000000000000003226c9eac0379f04ba2b1e1e1fcd52ac26309aea0000000000000000000000003e14dc1b13c488a8d5d310918780c983bd5982e70000000000000000000000006eee6060f715257b970700bc2656de21dedf074c000000000000000000000000b0aabba4b2783a72c52956cdef62d438eca2d7a100000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000a0ec9e1542485700110688b3e6fbebbdf23cd90100000000000000000000000000000000000000000000000000000000000000177269636f636865742d6674772d32303232303530332d37000000000000000000
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.