Address Details
contract
0xf37A766Fb6684fA86842F88380E786C2bD32Ba4c
- Contract Name
- Superfluid
- Creator
- 0x748f10–9877ab at 0x277cf2–101fa0
- Balance
- 0 CELO ( )
- Locked CELO Balance
- 0.00 CELO
- Voting CELO Balance
- 0.00 CELO
- Pending Unlocked Gold
- 0.00 CELO
- Tokens
-
Fetching tokens...
- Transactions
- 0 Transactions
- Transfers
- 0 Transfers
- Gas Used
- Fetching gas used...
- Last Balance Update
- 18349124
This contract has been partially verified via Sourcify.
View contract in Sourcify repository
- Contract name:
- Superfluid
- Optimization enabled
- true
- Compiler version
- v0.8.16+commit.07a7930e
- Optimization runs
- 200
- EVM Version
- london
- Verified at
- 2023-03-21T05:13:55.605092Z
project:/contracts/superfluid/Superfluid.sol
// SPDX-License-Identifier: AGPLv3 pragma solidity 0.8.16; import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol"; import { UUPSProxiable } from "../upgradability/UUPSProxiable.sol"; import { UUPSProxy } from "../upgradability/UUPSProxy.sol"; import { ISuperfluid, ISuperfluidGovernance, ISuperAgreement, ISuperApp, SuperAppDefinitions, ContextDefinitions, BatchOperation, SuperfluidGovernanceConfigs, ISuperfluidToken, ISuperToken, ISuperTokenFactory, IERC20 } from "../interfaces/superfluid/ISuperfluid.sol"; import { CallUtils } from "../libs/CallUtils.sol"; import { BaseRelayRecipient } from "../libs/BaseRelayRecipient.sol"; /** * @dev The Superfluid host implementation. * * NOTE: * - Please read ISuperfluid for implementation notes. * - For some deeper technical notes, please visit protocol-monorepo wiki area. * * @author Superfluid */ contract Superfluid is UUPSProxiable, ISuperfluid, BaseRelayRecipient { using SafeCast for uint256; struct AppManifest { uint256 configWord; } // solhint-disable-next-line var-name-mixedcase bool immutable public NON_UPGRADABLE_DEPLOYMENT; // solhint-disable-next-line var-name-mixedcase bool immutable public APP_WHITE_LISTING_ENABLED; /** * @dev Maximum number of level of apps can be composed together * * NOTE: * - TODO Composite app feature is currently disabled. Hence app cannot * will not be able to call other app. */ // solhint-disable-next-line var-name-mixedcase uint constant internal MAX_APP_CALLBACK_LEVEL = 1; // solhint-disable-next-line var-name-mixedcase uint64 constant public CALLBACK_GAS_LIMIT = 3000000; /* WARNING: NEVER RE-ORDER VARIABLES! Always double-check that new variables are added APPEND-ONLY. Re-ordering variables can permanently BREAK the deployed proxy contract. */ /// @dev Governance contract ISuperfluidGovernance internal _gov; /// @dev Agreement list indexed by agreement index minus one ISuperAgreement[] internal _agreementClasses; /// @dev Mapping between agreement type to agreement index (starting from 1) mapping (bytes32 => uint) internal _agreementClassIndices; /// @dev Super token ISuperTokenFactory internal _superTokenFactory; /// @dev App manifests mapping(ISuperApp => AppManifest) internal _appManifests; /// @dev Composite app white-listing: source app => (target app => isAllowed) mapping(ISuperApp => mapping(ISuperApp => bool)) internal _compositeApps; /// @dev Ctx stamp of the current transaction, it should always be cleared to /// zero before transaction finishes bytes32 internal _ctxStamp; /// @dev if app whitelisting is enabled, this is to make sure the keys are used only once mapping(bytes32 => bool) internal _appKeysUsedDeprecated; /// NOTE: Whenever modifying the storage layout here it is important to update the validateStorageLayout /// function in its respective mock contract to ensure that it doesn't break anything or lead to unexpected /// behaviors/layout when upgrading constructor(bool nonUpgradable, bool appWhiteListingEnabled) { NON_UPGRADABLE_DEPLOYMENT = nonUpgradable; APP_WHITE_LISTING_ENABLED = appWhiteListingEnabled; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // UUPSProxiable //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function initialize( ISuperfluidGovernance gov ) external initializer // OpenZeppelin Initializable { _gov = gov; } function proxiableUUID() public pure override returns (bytes32) { return keccak256("org.superfluid-finance.contracts.Superfluid.implementation"); } function updateCode(address newAddress) external override onlyGovernance { if (NON_UPGRADABLE_DEPLOYMENT) revert HOST_NON_UPGRADEABLE(); if (Superfluid(newAddress).NON_UPGRADABLE_DEPLOYMENT()) revert HOST_CANNOT_DOWNGRADE_TO_NON_UPGRADEABLE(); _updateCodeAddress(newAddress); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Time //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function getNow() public view returns (uint256) { // solhint-disable-next-line not-rely-on-time return block.timestamp; } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Governance //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function getGovernance() external view override returns (ISuperfluidGovernance) { return _gov; } function replaceGovernance(ISuperfluidGovernance newGov) external override onlyGovernance { emit GovernanceReplaced(_gov, newGov); _gov = newGov; } /************************************************************************** * Agreement Whitelisting *************************************************************************/ function registerAgreementClass(ISuperAgreement agreementClassLogic) external onlyGovernance override { bytes32 agreementType = agreementClassLogic.agreementType(); if (_agreementClassIndices[agreementType] != 0) { revert HOST_AGREEMENT_ALREADY_REGISTERED(); } if (_agreementClasses.length >= 256) revert HOST_MAX_256_AGREEMENTS(); ISuperAgreement agreementClass; if (!NON_UPGRADABLE_DEPLOYMENT) { // initialize the proxy UUPSProxy proxy = new UUPSProxy(); proxy.initializeProxy(address(agreementClassLogic)); agreementClass = ISuperAgreement(address(proxy)); } else { agreementClass = ISuperAgreement(address(agreementClassLogic)); } // register the agreement proxy _agreementClasses.push((agreementClass)); _agreementClassIndices[agreementType] = _agreementClasses.length; emit AgreementClassRegistered(agreementType, address(agreementClassLogic)); } function updateAgreementClass(ISuperAgreement agreementClassLogic) external onlyGovernance override { if (NON_UPGRADABLE_DEPLOYMENT) revert HOST_NON_UPGRADEABLE(); bytes32 agreementType = agreementClassLogic.agreementType(); uint idx = _agreementClassIndices[agreementType]; if (idx == 0) { revert HOST_AGREEMENT_IS_NOT_REGISTERED(); } UUPSProxiable proxiable = UUPSProxiable(address(_agreementClasses[idx - 1])); proxiable.updateCode(address(agreementClassLogic)); emit AgreementClassUpdated(agreementType, address(agreementClassLogic)); } function isAgreementTypeListed(bytes32 agreementType) external view override returns (bool yes) { uint idx = _agreementClassIndices[agreementType]; return idx != 0; } function isAgreementClassListed(ISuperAgreement agreementClass) public view override returns (bool yes) { bytes32 agreementType = agreementClass.agreementType(); uint idx = _agreementClassIndices[agreementType]; // it should also be the same agreement class proxy address return idx != 0 && _agreementClasses[idx - 1] == agreementClass; } function getAgreementClass(bytes32 agreementType) external view override returns(ISuperAgreement agreementClass) { uint idx = _agreementClassIndices[agreementType]; if (idx == 0) { revert HOST_AGREEMENT_IS_NOT_REGISTERED(); } return ISuperAgreement(_agreementClasses[idx - 1]); } function mapAgreementClasses(uint256 bitmap) external view override returns (ISuperAgreement[] memory agreementClasses) { uint i; uint n; // create memory output using the counted size agreementClasses = new ISuperAgreement[](_agreementClasses.length); // add to the output n = 0; for (i = 0; i < _agreementClasses.length; ++i) { if ((bitmap & (1 << i)) > 0) { agreementClasses[n++] = _agreementClasses[i]; } } // resize memory arrays assembly { mstore(agreementClasses, n) } } function addToAgreementClassesBitmap(uint256 bitmap, bytes32 agreementType) external view override returns (uint256 newBitmap) { uint idx = _agreementClassIndices[agreementType]; if (idx == 0) { revert HOST_AGREEMENT_IS_NOT_REGISTERED(); } return bitmap | (1 << (idx - 1)); } function removeFromAgreementClassesBitmap(uint256 bitmap, bytes32 agreementType) external view override returns (uint256 newBitmap) { uint idx = _agreementClassIndices[agreementType]; if (idx == 0) { revert HOST_AGREEMENT_IS_NOT_REGISTERED(); } return bitmap & ~(1 << (idx - 1)); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Super Token Factory //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function getSuperTokenFactory() external view override returns (ISuperTokenFactory factory) { return _superTokenFactory; } function getSuperTokenFactoryLogic() external view override returns (address logic) { assert(address(_superTokenFactory) != address(0)); if (NON_UPGRADABLE_DEPLOYMENT) return address(_superTokenFactory); else return UUPSProxiable(address(_superTokenFactory)).getCodeAddress(); } function updateSuperTokenFactory(ISuperTokenFactory newFactory) external override onlyGovernance { if (address(_superTokenFactory) == address(0)) { if (!NON_UPGRADABLE_DEPLOYMENT) { // initialize the proxy UUPSProxy proxy = new UUPSProxy(); proxy.initializeProxy(address(newFactory)); _superTokenFactory = ISuperTokenFactory(address(proxy)); } else { _superTokenFactory = newFactory; } _superTokenFactory.initialize(); } else { if (NON_UPGRADABLE_DEPLOYMENT) revert HOST_NON_UPGRADEABLE(); UUPSProxiable(address(_superTokenFactory)).updateCode(address(newFactory)); } emit SuperTokenFactoryUpdated(_superTokenFactory); } function updateSuperTokenLogic(ISuperToken token) external override onlyGovernance { address code = address(_superTokenFactory.getSuperTokenLogic()); // assuming it's uups proxiable UUPSProxiable(address(token)).updateCode(code); emit SuperTokenLogicUpdated(token, code); } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // App Registry //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// function registerApp( uint256 configWord ) external override { // check if whitelisting required if (APP_WHITE_LISTING_ENABLED) { revert HOST_NO_APP_REGISTRATION_PERMISSIONS(); } _registerApp(configWord, ISuperApp(msg.sender), true); } function registerAppWithKey(uint256 configWord, string calldata registrationKey) external override { if (APP_WHITE_LISTING_ENABLED) { bytes32 configKey = SuperfluidGovernanceConfigs.getAppRegistrationConfigKey( // solhint-disable-next-line avoid-tx-origin tx.origin, registrationKey ); // check if the key is valid and not expired if ( _gov.getConfigAsUint256( this, ISuperfluidToken(address(0)), configKey // solhint-disable-next-line not-rely-on-time ) < block.timestamp) revert HOST_INVALID_OR_EXPIRED_SUPER_APP_REGISTRATION_KEY(); } _registerApp(configWord, ISuperApp(msg.sender), true); } function registerAppByFactory( ISuperApp app, uint256 configWord ) external override { // msg sender must be a contract { uint256 cs; // solhint-disable-next-line no-inline-assembly assembly { cs := extcodesize(caller()) } if (cs == 0) revert HOST_MUST_BE_CONTRACT(); } if (APP_WHITE_LISTING_ENABLED) { // check if msg sender is authorized to register bytes32 configKey = SuperfluidGovernanceConfigs.getAppFactoryConfigKey(msg.sender); bool isAuthorizedAppFactory = _gov.getConfigAsUint256( this, ISuperfluidToken(address(0)), configKey) == 1; if (!isAuthorizedAppFactory) revert HOST_UNAUTHORIZED_SUPER_APP_FACTORY(); } _registerApp(configWord, app, false); } function _registerApp(uint256 configWord, ISuperApp app, bool checkIfInAppConstructor) private { // solhint-disable-next-line avoid-tx-origin if (msg.sender == tx.origin) { revert APP_RULE(SuperAppDefinitions.APP_RULE_NO_REGISTRATION_FOR_EOA); } if (checkIfInAppConstructor) { uint256 cs; // solhint-disable-next-line no-inline-assembly assembly { cs := extcodesize(app) } if (cs != 0) { revert APP_RULE(SuperAppDefinitions.APP_RULE_REGISTRATION_ONLY_IN_CONSTRUCTOR); } } if ( !SuperAppDefinitions.isConfigWordClean(configWord) || SuperAppDefinitions.getAppCallbackLevel(configWord) == 0 || (configWord & SuperAppDefinitions.APP_JAIL_BIT) != 0 ) { revert HOST_INVALID_CONFIG_WORD(); } if (_appManifests[ISuperApp(app)].configWord != 0) revert HOST_SUPER_APP_ALREADY_REGISTERED(); _appManifests[ISuperApp(app)] = AppManifest(configWord); emit AppRegistered(app); } function isApp(ISuperApp app) public view override returns(bool) { return _appManifests[app].configWord > 0; } function getAppCallbackLevel(ISuperApp appAddr) public override view returns(uint8) { return SuperAppDefinitions.getAppCallbackLevel(_appManifests[appAddr].configWord); } function getAppManifest( ISuperApp app ) external view override returns ( bool isSuperApp, bool isJailed, uint256 noopMask ) { AppManifest memory manifest = _appManifests[app]; isSuperApp = (manifest.configWord > 0); if (isSuperApp) { isJailed = SuperAppDefinitions.isAppJailed(manifest.configWord); noopMask = manifest.configWord & SuperAppDefinitions.AGREEMENT_CALLBACK_NOOP_BITMASKS; } } function isAppJailed( ISuperApp app ) external view override returns(bool) { return SuperAppDefinitions.isAppJailed(_appManifests[app].configWord); } function allowCompositeApp( ISuperApp targetApp ) external override { ISuperApp sourceApp = ISuperApp(msg.sender); if (!isApp(sourceApp)) revert HOST_SENDER_IS_NOT_SUPER_APP(); if (!isApp(targetApp)) revert HOST_RECEIVER_IS_NOT_SUPER_APP(); if (getAppCallbackLevel(sourceApp) <= getAppCallbackLevel(targetApp)) { revert HOST_SOURCE_APP_NEEDS_HIGHER_APP_LEVEL(); } _compositeApps[sourceApp][targetApp] = true; } function isCompositeAppAllowed( ISuperApp app, ISuperApp targetApp ) external view override returns (bool) { return _compositeApps[app][targetApp]; } /************************************************************************** * Agreement Framework *************************************************************************/ function callAppBeforeCallback( ISuperApp app, bytes calldata callData, bool isTermination, bytes calldata ctx ) external override onlyAgreement assertValidCtx(ctx) returns(bytes memory cbdata) { (bool success, bytes memory returnedData) = _callCallback(app, true, isTermination, callData, ctx); if (success) { if (CallUtils.isValidAbiEncodedBytes(returnedData)) { cbdata = abi.decode(returnedData, (bytes)); } else { if (!isTermination) { revert APP_RULE(SuperAppDefinitions.APP_RULE_CTX_IS_MALFORMATED); } else { _jailApp(app, SuperAppDefinitions.APP_RULE_CTX_IS_MALFORMATED); } } } } function callAppAfterCallback( ISuperApp app, bytes calldata callData, bool isTermination, bytes calldata ctx ) external override onlyAgreement assertValidCtx(ctx) returns(bytes memory newCtx) { (bool success, bytes memory returnedData) = _callCallback(app, false, isTermination, callData, ctx); if (success) { // the non static callback should not return empty ctx if (CallUtils.isValidAbiEncodedBytes(returnedData)) { newCtx = abi.decode(returnedData, (bytes)); if (!_isCtxValid(newCtx)) { if (!isTermination) { revert APP_RULE(SuperAppDefinitions.APP_RULE_CTX_IS_READONLY); } else { newCtx = ctx; _jailApp(app, SuperAppDefinitions.APP_RULE_CTX_IS_READONLY); } } } else { if (!isTermination) { revert APP_RULE(SuperAppDefinitions.APP_RULE_CTX_IS_MALFORMATED); } else { newCtx = ctx; _jailApp(app, SuperAppDefinitions.APP_RULE_CTX_IS_MALFORMATED); } } } else { newCtx = ctx; } } function appCallbackPush( bytes calldata ctx, ISuperApp app, uint256 appCreditGranted, int256 appCreditUsed, ISuperfluidToken appCreditToken ) external override onlyAgreement assertValidCtx(ctx) returns (bytes memory appCtx) { Context memory context = decodeCtx(ctx); // NOTE: we use 1 as a magic number here as we want to do this check once we are in a callback // we use 1 instead of MAX_APP_CALLBACK_LEVEL because 1 captures what we are trying to enforce if (isApp(ISuperApp(context.msgSender)) && context.appCallbackLevel >= 1) { if (!_compositeApps[ISuperApp(context.msgSender)][app]) { revert APP_RULE(SuperAppDefinitions.APP_RULE_COMPOSITE_APP_IS_NOT_WHITELISTED); } } context.appCallbackLevel++; context.callType = ContextDefinitions.CALL_INFO_CALL_TYPE_APP_CALLBACK; context.appCreditGranted = appCreditGranted; context.appCreditUsed = appCreditUsed; context.appAddress = address(app); context.appCreditToken = appCreditToken; appCtx = _updateContext(context); } function appCallbackPop( bytes calldata ctx, int256 appCreditUsedDelta ) external override onlyAgreement returns (bytes memory newCtx) { Context memory context = decodeCtx(ctx); context.appCreditUsed += appCreditUsedDelta; newCtx = _updateContext(context); } function ctxUseCredit( bytes calldata ctx, int256 appCreditUsedMore ) external override onlyAgreement assertValidCtx(ctx) returns (bytes memory newCtx) { Context memory context = decodeCtx(ctx); context.appCreditUsed += appCreditUsedMore; newCtx = _updateContext(context); } function jailApp( bytes calldata ctx, ISuperApp app, uint256 reason ) external override onlyAgreement assertValidCtx(ctx) returns (bytes memory newCtx) { _jailApp(app, reason); return ctx; } /************************************************************************** * Contextless Call Proxies *************************************************************************/ function _callAgreement( address msgSender, ISuperAgreement agreementClass, bytes memory callData, bytes memory userData ) internal cleanCtx isAgreement(agreementClass) returns(bytes memory returnedData) { // beware of the endianness bytes4 agreementSelector = CallUtils.parseSelector(callData); //Build context data bytes memory ctx = _updateContext(Context({ appCallbackLevel: 0, callType: ContextDefinitions.CALL_INFO_CALL_TYPE_AGREEMENT, timestamp: getNow(), msgSender: msgSender, agreementSelector: agreementSelector, userData: userData, appCreditGranted: 0, appCreditWantedDeprecated: 0, appCreditUsed: 0, appAddress: address(0), appCreditToken: ISuperfluidToken(address(0)) })); bool success; (success, returnedData) = _callExternalWithReplacedCtx(address(agreementClass), callData, ctx); if (!success) { CallUtils.revertFromReturnedData(returnedData); } // clear the stamp _ctxStamp = 0; } function callAgreement( ISuperAgreement agreementClass, bytes memory callData, bytes memory userData ) external override returns(bytes memory returnedData) { return _callAgreement(msg.sender, agreementClass, callData, userData); } function _callAppAction( address msgSender, ISuperApp app, bytes memory callData ) internal cleanCtx isAppActive(app) isValidAppAction(callData) returns(bytes memory returnedData) { // Build context data bytes memory ctx = _updateContext(Context({ appCallbackLevel: 0, callType: ContextDefinitions.CALL_INFO_CALL_TYPE_APP_ACTION, timestamp: getNow(), msgSender: msgSender, agreementSelector: 0, userData: "", appCreditGranted: 0, appCreditWantedDeprecated: 0, appCreditUsed: 0, appAddress: address(app), appCreditToken: ISuperfluidToken(address(0)) })); bool success; (success, returnedData) = _callExternalWithReplacedCtx(address(app), callData, ctx); if (success) { ctx = abi.decode(returnedData, (bytes)); if (!_isCtxValid(ctx)) revert APP_RULE(SuperAppDefinitions.APP_RULE_CTX_IS_READONLY); } else { CallUtils.revertFromReturnedData(returnedData); } // clear the stamp _ctxStamp = 0; } function callAppAction( ISuperApp app, bytes memory callData ) external override // NOTE: modifiers are called in _callAppAction returns(bytes memory returnedData) { return _callAppAction(msg.sender, app, callData); } /************************************************************************** * Contextual Call Proxies *************************************************************************/ function callAgreementWithContext( ISuperAgreement agreementClass, bytes calldata callData, bytes calldata userData, bytes calldata ctx ) external override requireValidCtx(ctx) isAgreement(agreementClass) returns (bytes memory newCtx, bytes memory returnedData) { Context memory context = decodeCtx(ctx); if (context.appAddress != msg.sender) revert HOST_CALL_AGREEMENT_WITH_CTX_FROM_WRONG_ADDRESS(); address oldSender = context.msgSender; context.msgSender = msg.sender; //context.agreementSelector =; context.userData = userData; newCtx = _updateContext(context); bool success; (success, returnedData) = _callExternalWithReplacedCtx(address(agreementClass), callData, newCtx); if (success) { (newCtx) = abi.decode(returnedData, (bytes)); assert(_isCtxValid(newCtx)); // back to old msg.sender context = decodeCtx(newCtx); context.msgSender = oldSender; newCtx = _updateContext(context); } else { CallUtils.revertFromReturnedData(returnedData); } } function callAppActionWithContext( ISuperApp app, bytes calldata callData, bytes calldata ctx ) external override requireValidCtx(ctx) isAppActive(app) isValidAppAction(callData) returns(bytes memory newCtx) { Context memory context = decodeCtx(ctx); if (context.appAddress != msg.sender) revert HOST_CALL_APP_ACTION_WITH_CTX_FROM_WRONG_ADDRESS(); address oldSender = context.msgSender; context.msgSender = msg.sender; newCtx = _updateContext(context); (bool success, bytes memory returnedData) = _callExternalWithReplacedCtx(address(app), callData, newCtx); if (success) { (newCtx) = abi.decode(returnedData, (bytes)); if (!_isCtxValid(newCtx)) revert APP_RULE(SuperAppDefinitions.APP_RULE_CTX_IS_READONLY); // back to old msg.sender context = decodeCtx(newCtx); context.msgSender = oldSender; newCtx = _updateContext(context); } else { CallUtils.revertFromReturnedData(returnedData); } } function decodeCtx(bytes memory ctx) public pure override returns (Context memory context) { return _decodeCtx(ctx); } function isCtxValid(bytes calldata ctx) external view override returns (bool) { return _isCtxValid(ctx); } /************************************************************************** * Batch call **************************************************************************/ function _batchCall( address msgSender, Operation[] calldata operations ) internal { for (uint256 i = 0; i < operations.length; ++i) { uint32 operationType = operations[i].operationType; if (operationType == BatchOperation.OPERATION_TYPE_ERC20_APPROVE) { (address spender, uint256 amount) = abi.decode(operations[i].data, (address, uint256)); ISuperToken(operations[i].target).operationApprove( msgSender, spender, amount); } else if (operationType == BatchOperation.OPERATION_TYPE_ERC20_TRANSFER_FROM) { (address sender, address receiver, uint256 amount) = abi.decode(operations[i].data, (address, address, uint256)); ISuperToken(operations[i].target).operationTransferFrom( msgSender, sender, receiver, amount); } else if (operationType == BatchOperation.OPERATION_TYPE_SUPERTOKEN_UPGRADE) { ISuperToken(operations[i].target).operationUpgrade( msgSender, abi.decode(operations[i].data, (uint256))); } else if (operationType == BatchOperation.OPERATION_TYPE_SUPERTOKEN_DOWNGRADE) { ISuperToken(operations[i].target).operationDowngrade( msgSender, abi.decode(operations[i].data, (uint256))); } else if (operationType == BatchOperation.OPERATION_TYPE_SUPERFLUID_CALL_AGREEMENT) { (bytes memory callData, bytes memory userData) = abi.decode(operations[i].data, (bytes, bytes)); _callAgreement( msgSender, ISuperAgreement(operations[i].target), callData, userData); } else if (operationType == BatchOperation.OPERATION_TYPE_SUPERFLUID_CALL_APP_ACTION) { _callAppAction( msgSender, ISuperApp(operations[i].target), operations[i].data); } else { revert HOST_UNKNOWN_BATCH_CALL_OPERATION_TYPE(); } } } /// @dev ISuperfluid.batchCall implementation function batchCall( Operation[] calldata operations ) external override { _batchCall(msg.sender, operations); } /// @dev ISuperfluid.forwardBatchCall implementation function forwardBatchCall(Operation[] calldata operations) external override { _batchCall(_getTransactionSigner(), operations); } /// @dev BaseRelayRecipient.isTrustedForwarder implementation function isTrustedForwarder(address forwarder) public view override returns(bool) { return _gov.getConfigAsUint256( this, ISuperfluidToken(address(0)), SuperfluidGovernanceConfigs.getTrustedForwarderConfigKey(forwarder) ) != 0; } /// @dev IRelayRecipient.isTrustedForwarder implementation function versionRecipient() external override pure returns (string memory) { return "v1"; } /************************************************************************** * Internal **************************************************************************/ function _jailApp(ISuperApp app, uint256 reason) internal { if ((_appManifests[app].configWord & SuperAppDefinitions.APP_JAIL_BIT) == 0) { _appManifests[app].configWord |= SuperAppDefinitions.APP_JAIL_BIT; emit Jail(app, reason); } } function _updateContext(Context memory context) private returns (bytes memory ctx) { if (context.appCallbackLevel > MAX_APP_CALLBACK_LEVEL) { revert APP_RULE(SuperAppDefinitions.APP_RULE_MAX_APP_LEVEL_REACHED); } uint256 callInfo = ContextDefinitions.encodeCallInfo(context.appCallbackLevel, context.callType); uint256 creditIO = context.appCreditGranted.toUint128() | (uint256(context.appCreditWantedDeprecated.toUint128()) << 128); // NOTE: nested encoding done due to stack too deep error when decoding in _decodeCtx ctx = abi.encode( abi.encode( callInfo, context.timestamp, context.msgSender, context.agreementSelector, context.userData ), abi.encode( creditIO, context.appCreditUsed, context.appAddress, context.appCreditToken ) ); _ctxStamp = keccak256(ctx); } function _decodeCtx(bytes memory ctx) private pure returns (Context memory context) { bytes memory ctx1; bytes memory ctx2; (ctx1, ctx2) = abi.decode(ctx, (bytes, bytes)); { uint256 callInfo; ( callInfo, context.timestamp, context.msgSender, context.agreementSelector, context.userData ) = abi.decode(ctx1, ( uint256, uint256, address, bytes4, bytes)); (context.appCallbackLevel, context.callType) = ContextDefinitions.decodeCallInfo(callInfo); } { uint256 creditIO; ( creditIO, context.appCreditUsed, context.appAddress, context.appCreditToken ) = abi.decode(ctx2, ( uint256, int256, address, ISuperfluidToken)); context.appCreditGranted = creditIO & type(uint128).max; context.appCreditWantedDeprecated = creditIO >> 128; } } function _isCtxValid(bytes memory ctx) private view returns (bool) { return ctx.length != 0 && keccak256(ctx) == _ctxStamp; } function _callExternalWithReplacedCtx( address target, bytes memory callData, bytes memory ctx ) private returns(bool success, bytes memory returnedData) { assert(target != address(0)); // STEP 1 : replace placeholder ctx with actual ctx callData = _replacePlaceholderCtx(callData, ctx); // STEP 2: Call external with replaced context /* solhint-disable-next-line avoid-low-level-calls */ (success, returnedData) = target.call(callData); // if target is not a contract or some arbitrary address, // success will be true and returnedData will be 0x (length = 0) // this leads to unintended behaviors, so we want to check to ensure // that the length of returnedData is greater than 0 if (success) { if (returnedData.length == 0) { revert APP_RULE(SuperAppDefinitions.APP_RULE_CTX_IS_MALFORMATED); } } } function _callCallback( ISuperApp app, bool isStaticall, bool isTermination, bytes memory callData, bytes memory ctx ) private returns(bool success, bytes memory returnedData) { assert(address(app) != address(0)); callData = _replacePlaceholderCtx(callData, ctx); uint256 gasLeftBefore = gasleft(); if (isStaticall) { /* solhint-disable-next-line avoid-low-level-calls*/ (success, returnedData) = address(app).staticcall{ gas: CALLBACK_GAS_LIMIT }(callData); } else { /* solhint-disable-next-line avoid-low-level-calls*/ (success, returnedData) = address(app).call{ gas: CALLBACK_GAS_LIMIT }(callData); } if (!success) { // "/ 63" is a magic to avoid out of gas attack. // See https://medium.com/@wighawag/ethereum-the-concept-of-gas-and-its-dangers-28d0eb809bb2. // A callback may use this to block the APP_RULE_NO_REVERT_ON_TERMINATION_CALLBACK jail rule. if (gasleft() > gasLeftBefore / 63) { if (!isTermination) { CallUtils.revertFromReturnedData(returnedData); } else { _jailApp(app, SuperAppDefinitions.APP_RULE_NO_REVERT_ON_TERMINATION_CALLBACK); } } else { // For legit out of gas issue, the call may still fail if more gas is provided // and this is okay, because there can be incentive to jail the app by providing // more gas. revert("SF: need more gas"); } } } /** * @dev Replace the placeholder ctx with the actual ctx */ function _replacePlaceholderCtx(bytes memory data, bytes memory ctx) internal pure returns (bytes memory dataWithCtx) { // 1.a ctx needs to be padded to align with 32 bytes boundary uint256 dataLen = data.length; // Double check if the ctx is a placeholder ctx // // NOTE: This can't check all cases - user can still put nonzero length of zero data // developer experience check. So this is more like a sanity check for clumsy app developers. // // So, agreements MUST NOT TRUST the ctx passed to it, and always use the isCtxValid first. { uint256 placeHolderCtxLength; // NOTE: len(data) is data.length + 32 https://docs.soliditylang.org/en/latest/abi-spec.html // solhint-disable-next-line no-inline-assembly assembly { placeHolderCtxLength := mload(add(data, dataLen)) } if (placeHolderCtxLength != 0) revert HOST_NON_ZERO_LENGTH_PLACEHOLDER_CTX(); } // 1.b remove the placeholder ctx // solhint-disable-next-line no-inline-assembly assembly { mstore(data, sub(dataLen, 0x20)) } // 1.c pack data with the replacement ctx return abi.encodePacked( data, // bytes with padded length uint256(ctx.length), ctx, new bytes(CallUtils.padLength32(ctx.length) - ctx.length) // ctx padding ); // NOTE: the alternative placeholderCtx is passing extra calldata to the agreements // agreements would use assembly code to read the ctx // Because selector is part of calldata, we do the padding internally, instead of // outside } modifier requireValidCtx(bytes memory ctx) { if (!_isCtxValid(ctx)) revert APP_RULE(SuperAppDefinitions.APP_RULE_CTX_IS_READONLY); _; } modifier assertValidCtx(bytes memory ctx) { assert(_isCtxValid(ctx)); _; } modifier cleanCtx() { if (_ctxStamp != 0) revert APP_RULE(SuperAppDefinitions.APP_RULE_CTX_IS_NOT_CLEAN); _; } modifier isAgreement(ISuperAgreement agreementClass) { if (!isAgreementClassListed(agreementClass)) { revert HOST_ONLY_LISTED_AGREEMENT(); } _; } modifier onlyGovernance() { if (msg.sender != address(_gov)) revert HOST_ONLY_GOVERNANCE(); _; } modifier onlyAgreement() { if (!isAgreementClassListed(ISuperAgreement(msg.sender))) { revert HOST_ONLY_LISTED_AGREEMENT(); } _; } modifier isAppActive(ISuperApp app) { uint256 configWord = _appManifests[app].configWord; if (configWord == 0) revert HOST_NOT_A_SUPER_APP(); if (SuperAppDefinitions.isAppJailed(configWord)) revert HOST_SUPER_APP_IS_JAILED(); _; } modifier isValidAppAction(bytes memory callData) { bytes4 actionSelector = CallUtils.parseSelector(callData); if (actionSelector == ISuperApp.beforeAgreementCreated.selector || actionSelector == ISuperApp.afterAgreementCreated.selector || actionSelector == ISuperApp.beforeAgreementUpdated.selector || actionSelector == ISuperApp.afterAgreementUpdated.selector || actionSelector == ISuperApp.beforeAgreementTerminated.selector || actionSelector == ISuperApp.afterAgreementTerminated.selector) { revert HOST_AGREEMENT_CALLBACK_IS_NOT_ACTION(); } _; } }
/_openzeppelin/contracts/proxy/Proxy.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol) pragma solidity ^0.8.0; /** * @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM * instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to * be specified by overriding the virtual {_implementation} function. * * Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a * different contract through the {_delegate} function. * * The success and return data of the delegated call will be returned back to the caller of the proxy. */ abstract contract Proxy { /** * @dev Delegates the current call to `implementation`. * * This function does not return to its internal call site, it will return directly to the external caller. */ function _delegate(address implementation) internal virtual { assembly { // Copy msg.data. We take full control of memory in this inline assembly // block because it will not return to Solidity code. We overwrite the // Solidity scratch pad at memory position 0. calldatacopy(0, 0, calldatasize()) // Call the implementation. // out and outsize are 0 because we don't know the size yet. let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0) // Copy the returned data. returndatacopy(0, 0, returndatasize()) switch result // delegatecall returns 0 on error. case 0 { revert(0, returndatasize()) } default { return(0, returndatasize()) } } } /** * @dev This is a virtual function that should be overridden so it returns the address to which the fallback function * and {_fallback} should delegate. */ function _implementation() internal view virtual returns (address); /** * @dev Delegates the current call to the address returned by `_implementation()`. * * This function does not return to its internal call site, it will return directly to the external caller. */ function _fallback() internal virtual { _beforeFallback(); _delegate(_implementation()); } /** * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other * function in the contract matches the call data. */ fallback() external payable virtual { _fallback(); } /** * @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data * is empty. */ receive() external payable virtual { _fallback(); } /** * @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback` * call, or as part of the Solidity `fallback` or `receive` functions. * * If overridden should call `super._beforeFallback()`. */ function _beforeFallback() internal virtual {} }
/_openzeppelin/contracts/proxy/utils/Initializable.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.2; 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 proxied contracts do not make use of 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. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ``` * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * 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 prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { bool isTopLevelCall = !_initializing; require( (isTopLevelCall && _initialized < 1) || (!Address.isContract(address(this)) && _initialized == 1), "Initializable: contract is already initialized" ); _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: setting the version to 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint8 version) { require(!_initializing && _initialized < version, "Initializable: contract is already initialized"); _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { require(!_initializing, "Initializable: contract is initializing"); if (_initialized < type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Internal function that returns the initialized version. Returns `_initialized` */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Internal function that returns the initialized version. Returns `_initializing` */ function _isInitializing() internal view returns (bool) { return _initializing; } }
/_openzeppelin/contracts/token/ERC20/IERC20.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
/_openzeppelin/contracts/token/ERC777/IERC777.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC777/IERC777.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC777Token standard as defined in the EIP. * * This contract uses the * https://eips.ethereum.org/EIPS/eip-1820[ERC1820 registry standard] to let * token holders and recipients react to token movements by using setting implementers * for the associated interfaces in said registry. See {IERC1820Registry} and * {ERC1820Implementer}. */ interface IERC777 { /** * @dev Emitted when `amount` tokens are created by `operator` and assigned to `to`. * * Note that some additional user `data` and `operatorData` can be logged in the event. */ event Minted(address indexed operator, address indexed to, uint256 amount, bytes data, bytes operatorData); /** * @dev Emitted when `operator` destroys `amount` tokens from `account`. * * Note that some additional user `data` and `operatorData` can be logged in the event. */ event Burned(address indexed operator, address indexed from, uint256 amount, bytes data, bytes operatorData); /** * @dev Emitted when `operator` is made operator for `tokenHolder`. */ event AuthorizedOperator(address indexed operator, address indexed tokenHolder); /** * @dev Emitted when `operator` is revoked its operator status for `tokenHolder`. */ event RevokedOperator(address indexed operator, address indexed tokenHolder); /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() external view returns (string memory); /** * @dev Returns the smallest part of the token that is not divisible. This * means all token operations (creation, movement and destruction) must have * amounts that are a multiple of this number. * * For most token contracts, this value will equal 1. */ function granularity() external view returns (uint256); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by an account (`owner`). */ function balanceOf(address owner) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * If send or receive hooks are registered for the caller and `recipient`, * the corresponding functions will be called with `data` and empty * `operatorData`. See {IERC777Sender} and {IERC777Recipient}. * * Emits a {Sent} event. * * Requirements * * - the caller must have at least `amount` tokens. * - `recipient` cannot be the zero address. * - if `recipient` is a contract, it must implement the {IERC777Recipient} * interface. */ function send( address recipient, uint256 amount, bytes calldata data ) external; /** * @dev Destroys `amount` tokens from the caller's account, reducing the * total supply. * * If a send hook is registered for the caller, the corresponding function * will be called with `data` and empty `operatorData`. See {IERC777Sender}. * * Emits a {Burned} event. * * Requirements * * - the caller must have at least `amount` tokens. */ function burn(uint256 amount, bytes calldata data) external; /** * @dev Returns true if an account is an operator of `tokenHolder`. * Operators can send and burn tokens on behalf of their owners. All * accounts are their own operator. * * See {operatorSend} and {operatorBurn}. */ function isOperatorFor(address operator, address tokenHolder) external view returns (bool); /** * @dev Make an account an operator of the caller. * * See {isOperatorFor}. * * Emits an {AuthorizedOperator} event. * * Requirements * * - `operator` cannot be calling address. */ function authorizeOperator(address operator) external; /** * @dev Revoke an account's operator status for the caller. * * See {isOperatorFor} and {defaultOperators}. * * Emits a {RevokedOperator} event. * * Requirements * * - `operator` cannot be calling address. */ function revokeOperator(address operator) external; /** * @dev Returns the list of default operators. These accounts are operators * for all token holders, even if {authorizeOperator} was never called on * them. * * This list is immutable, but individual holders may revoke these via * {revokeOperator}, in which case {isOperatorFor} will return false. */ function defaultOperators() external view returns (address[] memory); /** * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must * be an operator of `sender`. * * If send or receive hooks are registered for `sender` and `recipient`, * the corresponding functions will be called with `data` and * `operatorData`. See {IERC777Sender} and {IERC777Recipient}. * * Emits a {Sent} event. * * Requirements * * - `sender` cannot be the zero address. * - `sender` must have at least `amount` tokens. * - the caller must be an operator for `sender`. * - `recipient` cannot be the zero address. * - if `recipient` is a contract, it must implement the {IERC777Recipient} * interface. */ function operatorSend( address sender, address recipient, uint256 amount, bytes calldata data, bytes calldata operatorData ) external; /** * @dev Destroys `amount` tokens from `account`, reducing the total supply. * The caller must be an operator of `account`. * * If a send hook is registered for `account`, the corresponding function * will be called with `data` and `operatorData`. See {IERC777Sender}. * * Emits a {Burned} event. * * Requirements * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. * - the caller must be an operator for `account`. */ function operatorBurn( address account, uint256 amount, bytes calldata data, bytes calldata operatorData ) external; event Sent( address indexed operator, address indexed from, address indexed to, uint256 amount, bytes data, bytes operatorData ); }
/_openzeppelin/contracts/utils/Address.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @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 * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 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 functionCallWithValue(target, data, 0, "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"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, 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) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, 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) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or 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 { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // 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 /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
/_openzeppelin/contracts/utils/math/SafeCast.sol
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SafeCast.sol) // This file was procedurally generated from scripts/generate/templates/SafeCast.js. pragma solidity ^0.8.0; /** * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. * * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing * all math on `uint256` and `int256` and then downcasting. */ library SafeCast { /** * @dev Returns the downcasted uint248 from uint256, reverting on * overflow (when the input is greater than largest uint248). * * Counterpart to Solidity's `uint248` operator. * * Requirements: * * - input must fit into 248 bits * * _Available since v4.7._ */ function toUint248(uint256 value) internal pure returns (uint248) { require(value <= type(uint248).max, "SafeCast: value doesn't fit in 248 bits"); return uint248(value); } /** * @dev Returns the downcasted uint240 from uint256, reverting on * overflow (when the input is greater than largest uint240). * * Counterpart to Solidity's `uint240` operator. * * Requirements: * * - input must fit into 240 bits * * _Available since v4.7._ */ function toUint240(uint256 value) internal pure returns (uint240) { require(value <= type(uint240).max, "SafeCast: value doesn't fit in 240 bits"); return uint240(value); } /** * @dev Returns the downcasted uint232 from uint256, reverting on * overflow (when the input is greater than largest uint232). * * Counterpart to Solidity's `uint232` operator. * * Requirements: * * - input must fit into 232 bits * * _Available since v4.7._ */ function toUint232(uint256 value) internal pure returns (uint232) { require(value <= type(uint232).max, "SafeCast: value doesn't fit in 232 bits"); return uint232(value); } /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits * * _Available since v4.2._ */ function toUint224(uint256 value) internal pure returns (uint224) { require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits"); return uint224(value); } /** * @dev Returns the downcasted uint216 from uint256, reverting on * overflow (when the input is greater than largest uint216). * * Counterpart to Solidity's `uint216` operator. * * Requirements: * * - input must fit into 216 bits * * _Available since v4.7._ */ function toUint216(uint256 value) internal pure returns (uint216) { require(value <= type(uint216).max, "SafeCast: value doesn't fit in 216 bits"); return uint216(value); } /** * @dev Returns the downcasted uint208 from uint256, reverting on * overflow (when the input is greater than largest uint208). * * Counterpart to Solidity's `uint208` operator. * * Requirements: * * - input must fit into 208 bits * * _Available since v4.7._ */ function toUint208(uint256 value) internal pure returns (uint208) { require(value <= type(uint208).max, "SafeCast: value doesn't fit in 208 bits"); return uint208(value); } /** * @dev Returns the downcasted uint200 from uint256, reverting on * overflow (when the input is greater than largest uint200). * * Counterpart to Solidity's `uint200` operator. * * Requirements: * * - input must fit into 200 bits * * _Available since v4.7._ */ function toUint200(uint256 value) internal pure returns (uint200) { require(value <= type(uint200).max, "SafeCast: value doesn't fit in 200 bits"); return uint200(value); } /** * @dev Returns the downcasted uint192 from uint256, reverting on * overflow (when the input is greater than largest uint192). * * Counterpart to Solidity's `uint192` operator. * * Requirements: * * - input must fit into 192 bits * * _Available since v4.7._ */ function toUint192(uint256 value) internal pure returns (uint192) { require(value <= type(uint192).max, "SafeCast: value doesn't fit in 192 bits"); return uint192(value); } /** * @dev Returns the downcasted uint184 from uint256, reverting on * overflow (when the input is greater than largest uint184). * * Counterpart to Solidity's `uint184` operator. * * Requirements: * * - input must fit into 184 bits * * _Available since v4.7._ */ function toUint184(uint256 value) internal pure returns (uint184) { require(value <= type(uint184).max, "SafeCast: value doesn't fit in 184 bits"); return uint184(value); } /** * @dev Returns the downcasted uint176 from uint256, reverting on * overflow (when the input is greater than largest uint176). * * Counterpart to Solidity's `uint176` operator. * * Requirements: * * - input must fit into 176 bits * * _Available since v4.7._ */ function toUint176(uint256 value) internal pure returns (uint176) { require(value <= type(uint176).max, "SafeCast: value doesn't fit in 176 bits"); return uint176(value); } /** * @dev Returns the downcasted uint168 from uint256, reverting on * overflow (when the input is greater than largest uint168). * * Counterpart to Solidity's `uint168` operator. * * Requirements: * * - input must fit into 168 bits * * _Available since v4.7._ */ function toUint168(uint256 value) internal pure returns (uint168) { require(value <= type(uint168).max, "SafeCast: value doesn't fit in 168 bits"); return uint168(value); } /** * @dev Returns the downcasted uint160 from uint256, reverting on * overflow (when the input is greater than largest uint160). * * Counterpart to Solidity's `uint160` operator. * * Requirements: * * - input must fit into 160 bits * * _Available since v4.7._ */ function toUint160(uint256 value) internal pure returns (uint160) { require(value <= type(uint160).max, "SafeCast: value doesn't fit in 160 bits"); return uint160(value); } /** * @dev Returns the downcasted uint152 from uint256, reverting on * overflow (when the input is greater than largest uint152). * * Counterpart to Solidity's `uint152` operator. * * Requirements: * * - input must fit into 152 bits * * _Available since v4.7._ */ function toUint152(uint256 value) internal pure returns (uint152) { require(value <= type(uint152).max, "SafeCast: value doesn't fit in 152 bits"); return uint152(value); } /** * @dev Returns the downcasted uint144 from uint256, reverting on * overflow (when the input is greater than largest uint144). * * Counterpart to Solidity's `uint144` operator. * * Requirements: * * - input must fit into 144 bits * * _Available since v4.7._ */ function toUint144(uint256 value) internal pure returns (uint144) { require(value <= type(uint144).max, "SafeCast: value doesn't fit in 144 bits"); return uint144(value); } /** * @dev Returns the downcasted uint136 from uint256, reverting on * overflow (when the input is greater than largest uint136). * * Counterpart to Solidity's `uint136` operator. * * Requirements: * * - input must fit into 136 bits * * _Available since v4.7._ */ function toUint136(uint256 value) internal pure returns (uint136) { require(value <= type(uint136).max, "SafeCast: value doesn't fit in 136 bits"); return uint136(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v2.5._ */ function toUint128(uint256 value) internal pure returns (uint128) { require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits"); return uint128(value); } /** * @dev Returns the downcasted uint120 from uint256, reverting on * overflow (when the input is greater than largest uint120). * * Counterpart to Solidity's `uint120` operator. * * Requirements: * * - input must fit into 120 bits * * _Available since v4.7._ */ function toUint120(uint256 value) internal pure returns (uint120) { require(value <= type(uint120).max, "SafeCast: value doesn't fit in 120 bits"); return uint120(value); } /** * @dev Returns the downcasted uint112 from uint256, reverting on * overflow (when the input is greater than largest uint112). * * Counterpart to Solidity's `uint112` operator. * * Requirements: * * - input must fit into 112 bits * * _Available since v4.7._ */ function toUint112(uint256 value) internal pure returns (uint112) { require(value <= type(uint112).max, "SafeCast: value doesn't fit in 112 bits"); return uint112(value); } /** * @dev Returns the downcasted uint104 from uint256, reverting on * overflow (when the input is greater than largest uint104). * * Counterpart to Solidity's `uint104` operator. * * Requirements: * * - input must fit into 104 bits * * _Available since v4.7._ */ function toUint104(uint256 value) internal pure returns (uint104) { require(value <= type(uint104).max, "SafeCast: value doesn't fit in 104 bits"); return uint104(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits * * _Available since v4.2._ */ function toUint96(uint256 value) internal pure returns (uint96) { require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits"); return uint96(value); } /** * @dev Returns the downcasted uint88 from uint256, reverting on * overflow (when the input is greater than largest uint88). * * Counterpart to Solidity's `uint88` operator. * * Requirements: * * - input must fit into 88 bits * * _Available since v4.7._ */ function toUint88(uint256 value) internal pure returns (uint88) { require(value <= type(uint88).max, "SafeCast: value doesn't fit in 88 bits"); return uint88(value); } /** * @dev Returns the downcasted uint80 from uint256, reverting on * overflow (when the input is greater than largest uint80). * * Counterpart to Solidity's `uint80` operator. * * Requirements: * * - input must fit into 80 bits * * _Available since v4.7._ */ function toUint80(uint256 value) internal pure returns (uint80) { require(value <= type(uint80).max, "SafeCast: value doesn't fit in 80 bits"); return uint80(value); } /** * @dev Returns the downcasted uint72 from uint256, reverting on * overflow (when the input is greater than largest uint72). * * Counterpart to Solidity's `uint72` operator. * * Requirements: * * - input must fit into 72 bits * * _Available since v4.7._ */ function toUint72(uint256 value) internal pure returns (uint72) { require(value <= type(uint72).max, "SafeCast: value doesn't fit in 72 bits"); return uint72(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v2.5._ */ function toUint64(uint256 value) internal pure returns (uint64) { require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits"); return uint64(value); } /** * @dev Returns the downcasted uint56 from uint256, reverting on * overflow (when the input is greater than largest uint56). * * Counterpart to Solidity's `uint56` operator. * * Requirements: * * - input must fit into 56 bits * * _Available since v4.7._ */ function toUint56(uint256 value) internal pure returns (uint56) { require(value <= type(uint56).max, "SafeCast: value doesn't fit in 56 bits"); return uint56(value); } /** * @dev Returns the downcasted uint48 from uint256, reverting on * overflow (when the input is greater than largest uint48). * * Counterpart to Solidity's `uint48` operator. * * Requirements: * * - input must fit into 48 bits * * _Available since v4.7._ */ function toUint48(uint256 value) internal pure returns (uint48) { require(value <= type(uint48).max, "SafeCast: value doesn't fit in 48 bits"); return uint48(value); } /** * @dev Returns the downcasted uint40 from uint256, reverting on * overflow (when the input is greater than largest uint40). * * Counterpart to Solidity's `uint40` operator. * * Requirements: * * - input must fit into 40 bits * * _Available since v4.7._ */ function toUint40(uint256 value) internal pure returns (uint40) { require(value <= type(uint40).max, "SafeCast: value doesn't fit in 40 bits"); return uint40(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v2.5._ */ function toUint32(uint256 value) internal pure returns (uint32) { require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits"); return uint32(value); } /** * @dev Returns the downcasted uint24 from uint256, reverting on * overflow (when the input is greater than largest uint24). * * Counterpart to Solidity's `uint24` operator. * * Requirements: * * - input must fit into 24 bits * * _Available since v4.7._ */ function toUint24(uint256 value) internal pure returns (uint24) { require(value <= type(uint24).max, "SafeCast: value doesn't fit in 24 bits"); return uint24(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v2.5._ */ function toUint16(uint256 value) internal pure returns (uint16) { require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits"); return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits * * _Available since v2.5._ */ function toUint8(uint256 value) internal pure returns (uint8) { require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits"); return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. * * _Available since v3.0._ */ function toUint256(int256 value) internal pure returns (uint256) { require(value >= 0, "SafeCast: value must be positive"); return uint256(value); } /** * @dev Returns the downcasted int248 from int256, reverting on * overflow (when the input is less than smallest int248 or * greater than largest int248). * * Counterpart to Solidity's `int248` operator. * * Requirements: * * - input must fit into 248 bits * * _Available since v4.7._ */ function toInt248(int256 value) internal pure returns (int248 downcasted) { downcasted = int248(value); require(downcasted == value, "SafeCast: value doesn't fit in 248 bits"); } /** * @dev Returns the downcasted int240 from int256, reverting on * overflow (when the input is less than smallest int240 or * greater than largest int240). * * Counterpart to Solidity's `int240` operator. * * Requirements: * * - input must fit into 240 bits * * _Available since v4.7._ */ function toInt240(int256 value) internal pure returns (int240 downcasted) { downcasted = int240(value); require(downcasted == value, "SafeCast: value doesn't fit in 240 bits"); } /** * @dev Returns the downcasted int232 from int256, reverting on * overflow (when the input is less than smallest int232 or * greater than largest int232). * * Counterpart to Solidity's `int232` operator. * * Requirements: * * - input must fit into 232 bits * * _Available since v4.7._ */ function toInt232(int256 value) internal pure returns (int232 downcasted) { downcasted = int232(value); require(downcasted == value, "SafeCast: value doesn't fit in 232 bits"); } /** * @dev Returns the downcasted int224 from int256, reverting on * overflow (when the input is less than smallest int224 or * greater than largest int224). * * Counterpart to Solidity's `int224` operator. * * Requirements: * * - input must fit into 224 bits * * _Available since v4.7._ */ function toInt224(int256 value) internal pure returns (int224 downcasted) { downcasted = int224(value); require(downcasted == value, "SafeCast: value doesn't fit in 224 bits"); } /** * @dev Returns the downcasted int216 from int256, reverting on * overflow (when the input is less than smallest int216 or * greater than largest int216). * * Counterpart to Solidity's `int216` operator. * * Requirements: * * - input must fit into 216 bits * * _Available since v4.7._ */ function toInt216(int256 value) internal pure returns (int216 downcasted) { downcasted = int216(value); require(downcasted == value, "SafeCast: value doesn't fit in 216 bits"); } /** * @dev Returns the downcasted int208 from int256, reverting on * overflow (when the input is less than smallest int208 or * greater than largest int208). * * Counterpart to Solidity's `int208` operator. * * Requirements: * * - input must fit into 208 bits * * _Available since v4.7._ */ function toInt208(int256 value) internal pure returns (int208 downcasted) { downcasted = int208(value); require(downcasted == value, "SafeCast: value doesn't fit in 208 bits"); } /** * @dev Returns the downcasted int200 from int256, reverting on * overflow (when the input is less than smallest int200 or * greater than largest int200). * * Counterpart to Solidity's `int200` operator. * * Requirements: * * - input must fit into 200 bits * * _Available since v4.7._ */ function toInt200(int256 value) internal pure returns (int200 downcasted) { downcasted = int200(value); require(downcasted == value, "SafeCast: value doesn't fit in 200 bits"); } /** * @dev Returns the downcasted int192 from int256, reverting on * overflow (when the input is less than smallest int192 or * greater than largest int192). * * Counterpart to Solidity's `int192` operator. * * Requirements: * * - input must fit into 192 bits * * _Available since v4.7._ */ function toInt192(int256 value) internal pure returns (int192 downcasted) { downcasted = int192(value); require(downcasted == value, "SafeCast: value doesn't fit in 192 bits"); } /** * @dev Returns the downcasted int184 from int256, reverting on * overflow (when the input is less than smallest int184 or * greater than largest int184). * * Counterpart to Solidity's `int184` operator. * * Requirements: * * - input must fit into 184 bits * * _Available since v4.7._ */ function toInt184(int256 value) internal pure returns (int184 downcasted) { downcasted = int184(value); require(downcasted == value, "SafeCast: value doesn't fit in 184 bits"); } /** * @dev Returns the downcasted int176 from int256, reverting on * overflow (when the input is less than smallest int176 or * greater than largest int176). * * Counterpart to Solidity's `int176` operator. * * Requirements: * * - input must fit into 176 bits * * _Available since v4.7._ */ function toInt176(int256 value) internal pure returns (int176 downcasted) { downcasted = int176(value); require(downcasted == value, "SafeCast: value doesn't fit in 176 bits"); } /** * @dev Returns the downcasted int168 from int256, reverting on * overflow (when the input is less than smallest int168 or * greater than largest int168). * * Counterpart to Solidity's `int168` operator. * * Requirements: * * - input must fit into 168 bits * * _Available since v4.7._ */ function toInt168(int256 value) internal pure returns (int168 downcasted) { downcasted = int168(value); require(downcasted == value, "SafeCast: value doesn't fit in 168 bits"); } /** * @dev Returns the downcasted int160 from int256, reverting on * overflow (when the input is less than smallest int160 or * greater than largest int160). * * Counterpart to Solidity's `int160` operator. * * Requirements: * * - input must fit into 160 bits * * _Available since v4.7._ */ function toInt160(int256 value) internal pure returns (int160 downcasted) { downcasted = int160(value); require(downcasted == value, "SafeCast: value doesn't fit in 160 bits"); } /** * @dev Returns the downcasted int152 from int256, reverting on * overflow (when the input is less than smallest int152 or * greater than largest int152). * * Counterpart to Solidity's `int152` operator. * * Requirements: * * - input must fit into 152 bits * * _Available since v4.7._ */ function toInt152(int256 value) internal pure returns (int152 downcasted) { downcasted = int152(value); require(downcasted == value, "SafeCast: value doesn't fit in 152 bits"); } /** * @dev Returns the downcasted int144 from int256, reverting on * overflow (when the input is less than smallest int144 or * greater than largest int144). * * Counterpart to Solidity's `int144` operator. * * Requirements: * * - input must fit into 144 bits * * _Available since v4.7._ */ function toInt144(int256 value) internal pure returns (int144 downcasted) { downcasted = int144(value); require(downcasted == value, "SafeCast: value doesn't fit in 144 bits"); } /** * @dev Returns the downcasted int136 from int256, reverting on * overflow (when the input is less than smallest int136 or * greater than largest int136). * * Counterpart to Solidity's `int136` operator. * * Requirements: * * - input must fit into 136 bits * * _Available since v4.7._ */ function toInt136(int256 value) internal pure returns (int136 downcasted) { downcasted = int136(value); require(downcasted == value, "SafeCast: value doesn't fit in 136 bits"); } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v3.1._ */ function toInt128(int256 value) internal pure returns (int128 downcasted) { downcasted = int128(value); require(downcasted == value, "SafeCast: value doesn't fit in 128 bits"); } /** * @dev Returns the downcasted int120 from int256, reverting on * overflow (when the input is less than smallest int120 or * greater than largest int120). * * Counterpart to Solidity's `int120` operator. * * Requirements: * * - input must fit into 120 bits * * _Available since v4.7._ */ function toInt120(int256 value) internal pure returns (int120 downcasted) { downcasted = int120(value); require(downcasted == value, "SafeCast: value doesn't fit in 120 bits"); } /** * @dev Returns the downcasted int112 from int256, reverting on * overflow (when the input is less than smallest int112 or * greater than largest int112). * * Counterpart to Solidity's `int112` operator. * * Requirements: * * - input must fit into 112 bits * * _Available since v4.7._ */ function toInt112(int256 value) internal pure returns (int112 downcasted) { downcasted = int112(value); require(downcasted == value, "SafeCast: value doesn't fit in 112 bits"); } /** * @dev Returns the downcasted int104 from int256, reverting on * overflow (when the input is less than smallest int104 or * greater than largest int104). * * Counterpart to Solidity's `int104` operator. * * Requirements: * * - input must fit into 104 bits * * _Available since v4.7._ */ function toInt104(int256 value) internal pure returns (int104 downcasted) { downcasted = int104(value); require(downcasted == value, "SafeCast: value doesn't fit in 104 bits"); } /** * @dev Returns the downcasted int96 from int256, reverting on * overflow (when the input is less than smallest int96 or * greater than largest int96). * * Counterpart to Solidity's `int96` operator. * * Requirements: * * - input must fit into 96 bits * * _Available since v4.7._ */ function toInt96(int256 value) internal pure returns (int96 downcasted) { downcasted = int96(value); require(downcasted == value, "SafeCast: value doesn't fit in 96 bits"); } /** * @dev Returns the downcasted int88 from int256, reverting on * overflow (when the input is less than smallest int88 or * greater than largest int88). * * Counterpart to Solidity's `int88` operator. * * Requirements: * * - input must fit into 88 bits * * _Available since v4.7._ */ function toInt88(int256 value) internal pure returns (int88 downcasted) { downcasted = int88(value); require(downcasted == value, "SafeCast: value doesn't fit in 88 bits"); } /** * @dev Returns the downcasted int80 from int256, reverting on * overflow (when the input is less than smallest int80 or * greater than largest int80). * * Counterpart to Solidity's `int80` operator. * * Requirements: * * - input must fit into 80 bits * * _Available since v4.7._ */ function toInt80(int256 value) internal pure returns (int80 downcasted) { downcasted = int80(value); require(downcasted == value, "SafeCast: value doesn't fit in 80 bits"); } /** * @dev Returns the downcasted int72 from int256, reverting on * overflow (when the input is less than smallest int72 or * greater than largest int72). * * Counterpart to Solidity's `int72` operator. * * Requirements: * * - input must fit into 72 bits * * _Available since v4.7._ */ function toInt72(int256 value) internal pure returns (int72 downcasted) { downcasted = int72(value); require(downcasted == value, "SafeCast: value doesn't fit in 72 bits"); } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v3.1._ */ function toInt64(int256 value) internal pure returns (int64 downcasted) { downcasted = int64(value); require(downcasted == value, "SafeCast: value doesn't fit in 64 bits"); } /** * @dev Returns the downcasted int56 from int256, reverting on * overflow (when the input is less than smallest int56 or * greater than largest int56). * * Counterpart to Solidity's `int56` operator. * * Requirements: * * - input must fit into 56 bits * * _Available since v4.7._ */ function toInt56(int256 value) internal pure returns (int56 downcasted) { downcasted = int56(value); require(downcasted == value, "SafeCast: value doesn't fit in 56 bits"); } /** * @dev Returns the downcasted int48 from int256, reverting on * overflow (when the input is less than smallest int48 or * greater than largest int48). * * Counterpart to Solidity's `int48` operator. * * Requirements: * * - input must fit into 48 bits * * _Available since v4.7._ */ function toInt48(int256 value) internal pure returns (int48 downcasted) { downcasted = int48(value); require(downcasted == value, "SafeCast: value doesn't fit in 48 bits"); } /** * @dev Returns the downcasted int40 from int256, reverting on * overflow (when the input is less than smallest int40 or * greater than largest int40). * * Counterpart to Solidity's `int40` operator. * * Requirements: * * - input must fit into 40 bits * * _Available since v4.7._ */ function toInt40(int256 value) internal pure returns (int40 downcasted) { downcasted = int40(value); require(downcasted == value, "SafeCast: value doesn't fit in 40 bits"); } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v3.1._ */ function toInt32(int256 value) internal pure returns (int32 downcasted) { downcasted = int32(value); require(downcasted == value, "SafeCast: value doesn't fit in 32 bits"); } /** * @dev Returns the downcasted int24 from int256, reverting on * overflow (when the input is less than smallest int24 or * greater than largest int24). * * Counterpart to Solidity's `int24` operator. * * Requirements: * * - input must fit into 24 bits * * _Available since v4.7._ */ function toInt24(int256 value) internal pure returns (int24 downcasted) { downcasted = int24(value); require(downcasted == value, "SafeCast: value doesn't fit in 24 bits"); } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v3.1._ */ function toInt16(int256 value) internal pure returns (int16 downcasted) { downcasted = int16(value); require(downcasted == value, "SafeCast: value doesn't fit in 16 bits"); } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits * * _Available since v3.1._ */ function toInt8(int256 value) internal pure returns (int8 downcasted) { downcasted = int8(value); require(downcasted == value, "SafeCast: value doesn't fit in 8 bits"); } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. * * _Available since v3.0._ */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256"); return int256(value); } }
/project_/contracts/interfaces/superfluid/Definitions.sol
// SPDX-License-Identifier: AGPLv3 pragma solidity >= 0.8.4; /** * @title Super app definitions library * @author Superfluid */ library SuperAppDefinitions { /************************************************************************** / App manifest config word /**************************************************************************/ /* * App level is a way to allow the app to whitelist what other app it can * interact with (aka. composite app feature). * * For more details, refer to the technical paper of superfluid protocol. */ uint256 constant internal APP_LEVEL_MASK = 0xFF; // The app is at the final level, hence it doesn't want to interact with any other app uint256 constant internal APP_LEVEL_FINAL = 1 << 0; // The app is at the second level, it may interact with other final level apps if whitelisted uint256 constant internal APP_LEVEL_SECOND = 1 << 1; function getAppCallbackLevel(uint256 configWord) internal pure returns (uint8) { return uint8(configWord & APP_LEVEL_MASK); } uint256 constant internal APP_JAIL_BIT = 1 << 15; function isAppJailed(uint256 configWord) internal pure returns (bool) { return (configWord & SuperAppDefinitions.APP_JAIL_BIT) > 0; } /************************************************************************** / Callback implementation bit masks /**************************************************************************/ uint256 constant internal AGREEMENT_CALLBACK_NOOP_BITMASKS = 0xFF << 32; uint256 constant internal BEFORE_AGREEMENT_CREATED_NOOP = 1 << (32 + 0); uint256 constant internal AFTER_AGREEMENT_CREATED_NOOP = 1 << (32 + 1); uint256 constant internal BEFORE_AGREEMENT_UPDATED_NOOP = 1 << (32 + 2); uint256 constant internal AFTER_AGREEMENT_UPDATED_NOOP = 1 << (32 + 3); uint256 constant internal BEFORE_AGREEMENT_TERMINATED_NOOP = 1 << (32 + 4); uint256 constant internal AFTER_AGREEMENT_TERMINATED_NOOP = 1 << (32 + 5); /************************************************************************** / App Jail Reasons /**************************************************************************/ uint256 constant internal APP_RULE_REGISTRATION_ONLY_IN_CONSTRUCTOR = 1; uint256 constant internal APP_RULE_NO_REGISTRATION_FOR_EOA = 2; uint256 constant internal APP_RULE_NO_REVERT_ON_TERMINATION_CALLBACK = 10; uint256 constant internal APP_RULE_NO_CRITICAL_SENDER_ACCOUNT = 11; uint256 constant internal APP_RULE_NO_CRITICAL_RECEIVER_ACCOUNT = 12; uint256 constant internal APP_RULE_CTX_IS_READONLY = 20; uint256 constant internal APP_RULE_CTX_IS_NOT_CLEAN = 21; uint256 constant internal APP_RULE_CTX_IS_MALFORMATED = 22; uint256 constant internal APP_RULE_COMPOSITE_APP_IS_NOT_WHITELISTED = 30; uint256 constant internal APP_RULE_COMPOSITE_APP_IS_JAILED = 31; uint256 constant internal APP_RULE_MAX_APP_LEVEL_REACHED = 40; // Validate configWord cleaness for future compatibility, or else may introduce undefined future behavior function isConfigWordClean(uint256 configWord) internal pure returns (bool) { return (configWord & ~(APP_LEVEL_MASK | APP_JAIL_BIT | AGREEMENT_CALLBACK_NOOP_BITMASKS)) == uint256(0); } } /** * @title Context definitions library * @author Superfluid */ library ContextDefinitions { /************************************************************************** / Call info /**************************************************************************/ // app level uint256 constant internal CALL_INFO_APP_LEVEL_MASK = 0xFF; // call type uint256 constant internal CALL_INFO_CALL_TYPE_SHIFT = 32; uint256 constant internal CALL_INFO_CALL_TYPE_MASK = 0xF << CALL_INFO_CALL_TYPE_SHIFT; uint8 constant internal CALL_INFO_CALL_TYPE_AGREEMENT = 1; uint8 constant internal CALL_INFO_CALL_TYPE_APP_ACTION = 2; uint8 constant internal CALL_INFO_CALL_TYPE_APP_CALLBACK = 3; function decodeCallInfo(uint256 callInfo) internal pure returns (uint8 appCallbackLevel, uint8 callType) { appCallbackLevel = uint8(callInfo & CALL_INFO_APP_LEVEL_MASK); callType = uint8((callInfo & CALL_INFO_CALL_TYPE_MASK) >> CALL_INFO_CALL_TYPE_SHIFT); } function encodeCallInfo(uint8 appCallbackLevel, uint8 callType) internal pure returns (uint256 callInfo) { return uint256(appCallbackLevel) | (uint256(callType) << CALL_INFO_CALL_TYPE_SHIFT); } } /** * @title Flow Operator definitions library * @author Superfluid */ library FlowOperatorDefinitions { uint8 constant internal AUTHORIZE_FLOW_OPERATOR_CREATE = uint8(1) << 0; uint8 constant internal AUTHORIZE_FLOW_OPERATOR_UPDATE = uint8(1) << 1; uint8 constant internal AUTHORIZE_FLOW_OPERATOR_DELETE = uint8(1) << 2; uint8 constant internal AUTHORIZE_FULL_CONTROL = AUTHORIZE_FLOW_OPERATOR_CREATE | AUTHORIZE_FLOW_OPERATOR_UPDATE | AUTHORIZE_FLOW_OPERATOR_DELETE; uint8 constant internal REVOKE_FLOW_OPERATOR_CREATE = ~(uint8(1) << 0); uint8 constant internal REVOKE_FLOW_OPERATOR_UPDATE = ~(uint8(1) << 1); uint8 constant internal REVOKE_FLOW_OPERATOR_DELETE = ~(uint8(1) << 2); function isPermissionsClean(uint8 permissions) internal pure returns (bool) { return ( permissions & ~(AUTHORIZE_FLOW_OPERATOR_CREATE | AUTHORIZE_FLOW_OPERATOR_UPDATE | AUTHORIZE_FLOW_OPERATOR_DELETE) ) == uint8(0); } } /** * @title Batch operation library * @author Superfluid */ library BatchOperation { /** * @dev ERC20.approve batch operation type * * Call spec: * ISuperToken(target).operationApprove( * abi.decode(data, (address spender, uint256 amount)) * ) */ uint32 constant internal OPERATION_TYPE_ERC20_APPROVE = 1; /** * @dev ERC20.transferFrom batch operation type * * Call spec: * ISuperToken(target).operationTransferFrom( * abi.decode(data, (address sender, address recipient, uint256 amount) * ) */ uint32 constant internal OPERATION_TYPE_ERC20_TRANSFER_FROM = 2; /** * @dev SuperToken.upgrade batch operation type * * Call spec: * ISuperToken(target).operationUpgrade( * abi.decode(data, (uint256 amount) * ) */ uint32 constant internal OPERATION_TYPE_SUPERTOKEN_UPGRADE = 1 + 100; /** * @dev SuperToken.downgrade batch operation type * * Call spec: * ISuperToken(target).operationDowngrade( * abi.decode(data, (uint256 amount) * ) */ uint32 constant internal OPERATION_TYPE_SUPERTOKEN_DOWNGRADE = 2 + 100; /** * @dev Superfluid.callAgreement batch operation type * * Call spec: * callAgreement( * ISuperAgreement(target)), * abi.decode(data, (bytes calldata, bytes userdata) * ) */ uint32 constant internal OPERATION_TYPE_SUPERFLUID_CALL_AGREEMENT = 1 + 200; /** * @dev Superfluid.callAppAction batch operation type * * Call spec: * callAppAction( * ISuperApp(target)), * data * ) */ uint32 constant internal OPERATION_TYPE_SUPERFLUID_CALL_APP_ACTION = 2 + 200; } /** * @title Superfluid governance configs library * @author Superfluid */ library SuperfluidGovernanceConfigs { bytes32 constant internal SUPERFLUID_REWARD_ADDRESS_CONFIG_KEY = keccak256("org.superfluid-finance.superfluid.rewardAddress"); bytes32 constant internal CFAV1_PPP_CONFIG_KEY = keccak256("org.superfluid-finance.agreements.ConstantFlowAgreement.v1.PPPConfiguration"); bytes32 constant internal SUPERTOKEN_MINIMUM_DEPOSIT_KEY = keccak256("org.superfluid-finance.superfluid.superTokenMinimumDeposit"); function getTrustedForwarderConfigKey(address forwarder) internal pure returns (bytes32) { return keccak256(abi.encode( "org.superfluid-finance.superfluid.trustedForwarder", forwarder)); } function getAppRegistrationConfigKey(address deployer, string memory registrationKey) internal pure returns (bytes32) { return keccak256(abi.encode( "org.superfluid-finance.superfluid.appWhiteListing.registrationKey", deployer, registrationKey)); } function getAppFactoryConfigKey(address factory) internal pure returns (bytes32) { return keccak256(abi.encode( "org.superfluid-finance.superfluid.appWhiteListing.factory", factory)); } function decodePPPConfig(uint256 pppConfig) internal pure returns (uint256 liquidationPeriod, uint256 patricianPeriod) { liquidationPeriod = (pppConfig >> 32) & type(uint32).max; patricianPeriod = pppConfig & type(uint32).max; } }
/project_/contracts/interfaces/superfluid/ISuperAgreement.sol
// SPDX-License-Identifier: AGPLv3 pragma solidity >= 0.8.4; import { ISuperfluidToken } from "./ISuperfluidToken.sol"; /** * @title Super agreement interface * @author Superfluid */ interface ISuperAgreement { /** * @dev Get the type of the agreement class */ function agreementType() external view returns (bytes32); /** * @dev Calculate the real-time balance for the account of this agreement class * @param account Account the state belongs to * @param time Time used for the calculation * @return dynamicBalance Dynamic balance portion of real-time balance of this agreement * @return deposit Account deposit amount of this agreement * @return owedDeposit Account owed deposit amount of this agreement */ function realtimeBalanceOf( ISuperfluidToken token, address account, uint256 time ) external view returns ( int256 dynamicBalance, uint256 deposit, uint256 owedDeposit ); }
/project_/contracts/interfaces/superfluid/ISuperApp.sol
// SPDX-License-Identifier: AGPLv3 pragma solidity >= 0.8.4; import { ISuperToken } from "./ISuperToken.sol"; /** * @title SuperApp interface * @author Superfluid * @dev Be aware of the app being jailed, when the word permitted is used. */ interface ISuperApp { /** * @dev Callback before a new agreement is created. * @param superToken The super token used for the agreement. * @param agreementClass The agreement class address. * @param agreementId The agreementId * @param agreementData The agreement data (non-compressed) * @param ctx The context data. * @return cbdata A free format in memory data the app can use to pass * arbitary information to the after-hook callback. * * @custom:note * - It will be invoked with `staticcall`, no state changes are permitted. * - Only revert with a "reason" is permitted. */ function beforeAgreementCreated( ISuperToken superToken, address agreementClass, bytes32 agreementId, bytes calldata agreementData, bytes calldata ctx ) external view returns (bytes memory cbdata); /** * @dev Callback after a new agreement is created. * @param superToken The super token used for the agreement. * @param agreementClass The agreement class address. * @param agreementId The agreementId * @param agreementData The agreement data (non-compressed) * @param cbdata The data returned from the before-hook callback. * @param ctx The context data. * @return newCtx The current context of the transaction. * * @custom:note * - State changes is permitted. * - Only revert with a "reason" is permitted. */ function afterAgreementCreated( ISuperToken superToken, address agreementClass, bytes32 agreementId, bytes calldata agreementData, bytes calldata cbdata, bytes calldata ctx ) external returns (bytes memory newCtx); /** * @dev Callback before a new agreement is updated. * @param superToken The super token used for the agreement. * @param agreementClass The agreement class address. * @param agreementId The agreementId * @param agreementData The agreement data (non-compressed) * @param ctx The context data. * @return cbdata A free format in memory data the app can use to pass * arbitary information to the after-hook callback. * * @custom:note * - It will be invoked with `staticcall`, no state changes are permitted. * - Only revert with a "reason" is permitted. */ function beforeAgreementUpdated( ISuperToken superToken, address agreementClass, bytes32 agreementId, bytes calldata agreementData, bytes calldata ctx ) external view returns (bytes memory cbdata); /** * @dev Callback after a new agreement is updated. * @param superToken The super token used for the agreement. * @param agreementClass The agreement class address. * @param agreementId The agreementId * @param agreementData The agreement data (non-compressed) * @param cbdata The data returned from the before-hook callback. * @param ctx The context data. * @return newCtx The current context of the transaction. * * @custom:note * - State changes is permitted. * - Only revert with a "reason" is permitted. */ function afterAgreementUpdated( ISuperToken superToken, address agreementClass, bytes32 agreementId, bytes calldata agreementData, bytes calldata cbdata, bytes calldata ctx ) external returns (bytes memory newCtx); /** * @dev Callback before a new agreement is terminated. * @param superToken The super token used for the agreement. * @param agreementClass The agreement class address. * @param agreementId The agreementId * @param agreementData The agreement data (non-compressed) * @param ctx The context data. * @return cbdata A free format in memory data the app can use to pass arbitary information to the after-hook callback. * * @custom:note * - It will be invoked with `staticcall`, no state changes are permitted. * - Revert is not permitted. */ function beforeAgreementTerminated( ISuperToken superToken, address agreementClass, bytes32 agreementId, bytes calldata agreementData, bytes calldata ctx ) external view returns (bytes memory cbdata); /** * @dev Callback after a new agreement is terminated. * @param superToken The super token used for the agreement. * @param agreementClass The agreement class address. * @param agreementId The agreementId * @param agreementData The agreement data (non-compressed) * @param cbdata The data returned from the before-hook callback. * @param ctx The context data. * @return newCtx The current context of the transaction. * * @custom:note * - State changes is permitted. * - Revert is not permitted. */ function afterAgreementTerminated( ISuperToken superToken, address agreementClass, bytes32 agreementId, bytes calldata agreementData, bytes calldata cbdata, bytes calldata ctx ) external returns (bytes memory newCtx); }
/project_/contracts/interfaces/superfluid/ISuperToken.sol
// SPDX-License-Identifier: AGPLv3 pragma solidity >= 0.8.4; import { ISuperfluid } from "./ISuperfluid.sol"; import { ISuperfluidToken } from "./ISuperfluidToken.sol"; import { TokenInfo } from "../tokens/TokenInfo.sol"; import { IERC777 } from "@openzeppelin/contracts/token/ERC777/IERC777.sol"; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; /** * @title Super token (Superfluid Token + ERC20 + ERC777) interface * @author Superfluid */ interface ISuperToken is ISuperfluidToken, TokenInfo, IERC20, IERC777 { /************************************************************************** * Errors *************************************************************************/ error SUPER_TOKEN_CALLER_IS_NOT_OPERATOR_FOR_HOLDER(); // 0xf7f02227 error SUPER_TOKEN_NOT_ERC777_TOKENS_RECIPIENT(); // 0xfe737d05 error SUPER_TOKEN_INFLATIONARY_DEFLATIONARY_NOT_SUPPORTED(); // 0xe3e13698 error SUPER_TOKEN_NO_UNDERLYING_TOKEN(); // 0xf79cf656 error SUPER_TOKEN_ONLY_SELF(); // 0x7ffa6648 error SUPER_TOKEN_ONLY_HOST(); // 0x98f73704 error SUPER_TOKEN_APPROVE_FROM_ZERO_ADDRESS(); // 0x81638627 error SUPER_TOKEN_APPROVE_TO_ZERO_ADDRESS(); // 0xdf070274 error SUPER_TOKEN_BURN_FROM_ZERO_ADDRESS(); // 0xba2ab184 error SUPER_TOKEN_MINT_TO_ZERO_ADDRESS(); // 0x0d243157 error SUPER_TOKEN_TRANSFER_FROM_ZERO_ADDRESS(); // 0xeecd6c9b error SUPER_TOKEN_TRANSFER_TO_ZERO_ADDRESS(); // 0xe219bd39 /** * @dev Initialize the contract */ function initialize( IERC20 underlyingToken, uint8 underlyingDecimals, string calldata n, string calldata s ) external; /************************************************************************** * TokenInfo & ERC777 *************************************************************************/ /** * @dev Returns the name of the token. */ function name() external view override(IERC777, TokenInfo) returns (string memory); /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() external view override(IERC777, TokenInfo) returns (string memory); /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5,05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is * called. * * @custom:note SuperToken always uses 18 decimals. * * This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() external view override(TokenInfo) returns (uint8); /************************************************************************** * ERC20 & ERC777 *************************************************************************/ /** * @dev See {IERC20-totalSupply}. */ function totalSupply() external view override(IERC777, IERC20) returns (uint256); /** * @dev Returns the amount of tokens owned by an account (`owner`). */ function balanceOf(address account) external view override(IERC777, IERC20) returns(uint256 balance); /************************************************************************** * ERC20 *************************************************************************/ /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * @return Returns Success a boolean value indicating whether the operation succeeded. * * @custom:emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external override(IERC20) returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * @notice This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external override(IERC20) view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * @return Returns Success a boolean value indicating whether the operation succeeded. * * @custom:note Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * @custom:emits an {Approval} event. */ function approve(address spender, uint256 amount) external override(IERC20) returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * @return Returns Success a boolean value indicating whether the operation succeeded. * * @custom:emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external override(IERC20) returns (bool); /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * @custom:emits an {Approval} event indicating the updated allowance. * * @custom:requirements * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) external returns (bool); /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * @custom:emits an {Approval} event indicating the updated allowance. * * @custom:requirements * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool); /************************************************************************** * ERC777 *************************************************************************/ /** * @dev Returns the smallest part of the token that is not divisible. This * means all token operations (creation, movement and destruction) must have * amounts that are a multiple of this number. * * @custom:note For super token contracts, this value is always 1 */ function granularity() external view override(IERC777) returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * @dev If send or receive hooks are registered for the caller and `recipient`, * the corresponding functions will be called with `data` and empty * `operatorData`. See {IERC777Sender} and {IERC777Recipient}. * * @custom:emits a {Sent} event. * * @custom:requirements * - the caller must have at least `amount` tokens. * - `recipient` cannot be the zero address. * - if `recipient` is a contract, it must implement the {IERC777Recipient} * interface. */ function send(address recipient, uint256 amount, bytes calldata data) external override(IERC777); /** * @dev Destroys `amount` tokens from the caller's account, reducing the * total supply. * * If a send hook is registered for the caller, the corresponding function * will be called with `data` and empty `operatorData`. See {IERC777Sender}. * * @custom:emits a {Burned} event. * * @custom:requirements * - the caller must have at least `amount` tokens. */ function burn(uint256 amount, bytes calldata data) external override(IERC777); /** * @dev Returns true if an account is an operator of `tokenHolder`. * Operators can send and burn tokens on behalf of their owners. All * accounts are their own operator. * * See {operatorSend} and {operatorBurn}. */ function isOperatorFor(address operator, address tokenHolder) external override(IERC777) view returns (bool); /** * @dev Make an account an operator of the caller. * * See {isOperatorFor}. * * @custom:emits an {AuthorizedOperator} event. * * @custom:requirements * - `operator` cannot be calling address. */ function authorizeOperator(address operator) external override(IERC777); /** * @dev Revoke an account's operator status for the caller. * * See {isOperatorFor} and {defaultOperators}. * * @custom:emits a {RevokedOperator} event. * * @custom:requirements * - `operator` cannot be calling address. */ function revokeOperator(address operator) external override(IERC777); /** * @dev Returns the list of default operators. These accounts are operators * for all token holders, even if {authorizeOperator} was never called on * them. * * This list is immutable, but individual holders may revoke these via * {revokeOperator}, in which case {isOperatorFor} will return false. */ function defaultOperators() external override(IERC777) view returns (address[] memory); /** * @dev Moves `amount` tokens from `sender` to `recipient`. The caller must * be an operator of `sender`. * * If send or receive hooks are registered for `sender` and `recipient`, * the corresponding functions will be called with `data` and * `operatorData`. See {IERC777Sender} and {IERC777Recipient}. * * @custom:emits a {Sent} event. * * @custom:requirements * - `sender` cannot be the zero address. * - `sender` must have at least `amount` tokens. * - the caller must be an operator for `sender`. * - `recipient` cannot be the zero address. * - if `recipient` is a contract, it must implement the {IERC777Recipient} * interface. */ function operatorSend( address sender, address recipient, uint256 amount, bytes calldata data, bytes calldata operatorData ) external override(IERC777); /** * @dev Destroys `amount` tokens from `account`, reducing the total supply. * The caller must be an operator of `account`. * * If a send hook is registered for `account`, the corresponding function * will be called with `data` and `operatorData`. See {IERC777Sender}. * * @custom:emits a {Burned} event. * * @custom:requirements * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. * - the caller must be an operator for `account`. */ function operatorBurn( address account, uint256 amount, bytes calldata data, bytes calldata operatorData ) external override(IERC777); /************************************************************************** * SuperToken custom token functions *************************************************************************/ /** * @dev Mint new tokens for the account * * @custom:modifiers * - onlySelf */ function selfMint( address account, uint256 amount, bytes memory userData ) external; /** * @dev Burn existing tokens for the account * * @custom:modifiers * - onlySelf */ function selfBurn( address account, uint256 amount, bytes memory userData ) external; /** * @dev Transfer `amount` tokens from the `sender` to `recipient`. * If `spender` isn't the same as `sender`, checks if `spender` has allowance to * spend tokens of `sender`. * * @custom:modifiers * - onlySelf */ function selfTransferFrom( address sender, address spender, address recipient, uint256 amount ) external; /** * @dev Give `spender`, `amount` allowance to spend the tokens of * `account`. * * @custom:modifiers * - onlySelf */ function selfApproveFor( address account, address spender, uint256 amount ) external; /************************************************************************** * SuperToken extra functions *************************************************************************/ /** * @dev Transfer all available balance from `msg.sender` to `recipient` */ function transferAll(address recipient) external; /************************************************************************** * ERC20 wrapping *************************************************************************/ /** * @dev Return the underlying token contract * @return tokenAddr Underlying token address */ function getUnderlyingToken() external view returns(address tokenAddr); /** * @dev Upgrade ERC20 to SuperToken. * @param amount Number of tokens to be upgraded (in 18 decimals) * * @custom:note It will use `transferFrom` to get tokens. Before calling this * function you should `approve` this contract */ function upgrade(uint256 amount) external; /** * @dev Upgrade ERC20 to SuperToken and transfer immediately * @param to The account to received upgraded tokens * @param amount Number of tokens to be upgraded (in 18 decimals) * @param data User data for the TokensRecipient callback * * @custom:note It will use `transferFrom` to get tokens. Before calling this * function you should `approve` this contract */ function upgradeTo(address to, uint256 amount, bytes calldata data) external; /** * @dev Token upgrade event * @param account Account where tokens are upgraded to * @param amount Amount of tokens upgraded (in 18 decimals) */ event TokenUpgraded( address indexed account, uint256 amount ); /** * @dev Downgrade SuperToken to ERC20. * @dev It will call transfer to send tokens * @param amount Number of tokens to be downgraded */ function downgrade(uint256 amount) external; /** * @dev Token downgrade event * @param account Account whose tokens are upgraded * @param amount Amount of tokens downgraded */ event TokenDowngraded( address indexed account, uint256 amount ); /************************************************************************** * Batch Operations *************************************************************************/ /** * @dev Perform ERC20 approve by host contract. * @param account The account owner to be approved. * @param spender The spender of account owner's funds. * @param amount Number of tokens to be approved. * * @custom:modifiers * - onlyHost */ function operationApprove( address account, address spender, uint256 amount ) external; /** * @dev Perform ERC20 transfer from by host contract. * @param account The account to spend sender's funds. * @param spender The account where the funds is sent from. * @param recipient The recipient of thefunds. * @param amount Number of tokens to be transferred. * * @custom:modifiers * - onlyHost */ function operationTransferFrom( address account, address spender, address recipient, uint256 amount ) external; /** * @dev Upgrade ERC20 to SuperToken by host contract. * @param account The account to be changed. * @param amount Number of tokens to be upgraded (in 18 decimals) * * @custom:modifiers * - onlyHost */ function operationUpgrade(address account, uint256 amount) external; /** * @dev Downgrade ERC20 to SuperToken by host contract. * @param account The account to be changed. * @param amount Number of tokens to be downgraded (in 18 decimals) * * @custom:modifiers * - onlyHost */ function operationDowngrade(address account, uint256 amount) external; /************************************************************************** * Function modifiers for access control and parameter validations * * While they cannot be explicitly stated in function definitions, they are * listed in function definition comments instead for clarity. * * NOTE: solidity-coverage not supporting it *************************************************************************/ /// @dev The msg.sender must be the contract itself //modifier onlySelf() virtual }
/project_/contracts/interfaces/superfluid/ISuperTokenFactory.sol
// SPDX-License-Identifier: AGPLv3 pragma solidity >= 0.8.4; import { ISuperToken } from "./ISuperToken.sol"; import { IERC20, ERC20WithTokenInfo } from "../tokens/ERC20WithTokenInfo.sol"; /** * @title Super token factory interface * @author Superfluid */ interface ISuperTokenFactory { /************************************************************************** * Errors *************************************************************************/ error SUPER_TOKEN_FACTORY_ALREADY_EXISTS(); // 0x91d67972 error SUPER_TOKEN_FACTORY_DOES_NOT_EXIST(); // 0x872cac48 error SUPER_TOKEN_FACTORY_UNINITIALIZED(); // 0x1b39b9b4 error SUPER_TOKEN_FACTORY_ONLY_HOST(); // 0x478b8e83 error SUPER_TOKEN_FACTORY_ZERO_ADDRESS(); // 0x305c9e82 /** * @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_UPGRADABLE } /** * @notice 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 * @return superToken The deployed and initialized wrapper super token */ function createERC20Wrapper( IERC20 underlyingToken, uint8 underlyingDecimals, Upgradability upgradability, string calldata name, string calldata symbol ) external returns (ISuperToken superToken); /** * @notice 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 * @return superToken The deployed and initialized wrapper super token * NOTE: * - It assumes token provide the .decimals() function */ function createERC20Wrapper( ERC20WithTokenInfo underlyingToken, Upgradability upgradability, string calldata name, string calldata symbol ) external returns (ISuperToken superToken); /** * @notice Creates a wrapper super token AND sets it in the canonical list OR reverts if it already exists * @dev salt for create2 is the keccak256 hash of abi.encode(address(_underlyingToken)) * @param _underlyingToken Underlying ERC20 token * @return ISuperToken the created supertoken */ function createCanonicalERC20Wrapper(ERC20WithTokenInfo _underlyingToken) external returns (ISuperToken); /** * @notice Computes/Retrieves wrapper super token address given the underlying token address * @dev We return from our canonical list if it already exists, otherwise we compute it * @dev note that this function only computes addresses for SEMI_UPGRADABLE SuperTokens * @param _underlyingToken Underlying ERC20 token address * @return superTokenAddress Super token address * @return isDeployed whether the super token is deployed AND set in the canonical mapping */ function computeCanonicalERC20WrapperAddress(address _underlyingToken) external view returns (address superTokenAddress, bool isDeployed); /** * @notice Gets the canonical ERC20 wrapper super token address given the underlying token address * @dev We return the address if it exists and the zero address otherwise * @param _underlyingTokenAddress Underlying ERC20 token address * @return superTokenAddress Super token address */ function getCanonicalERC20Wrapper(address _underlyingTokenAddress) external view returns (address superTokenAddress); /** * @dev Creates a new custom super token * @param customSuperTokenProxy address of the custom supertoken proxy */ function initializeCustomSuperToken( address customSuperTokenProxy ) external; /** * @dev Super token logic created event * @param tokenLogic Token logic address */ event SuperTokenLogicCreated(ISuperToken indexed tokenLogic); /** * @dev Super token created event * @param token Newly created super token address */ event SuperTokenCreated(ISuperToken indexed token); /** * @dev Custom super token created event * @param token Newly created custom super token address */ event CustomSuperTokenCreated(ISuperToken indexed token); }
/project_/contracts/interfaces/superfluid/ISuperfluid.sol
// SPDX-License-Identifier: AGPLv3 pragma solidity >= 0.8.4; import { ISuperfluidGovernance } from "./ISuperfluidGovernance.sol"; import { ISuperfluidToken } from "./ISuperfluidToken.sol"; import { ISuperToken } from "./ISuperToken.sol"; import { ISuperTokenFactory } from "./ISuperTokenFactory.sol"; import { ISuperAgreement } from "./ISuperAgreement.sol"; import { ISuperApp } from "./ISuperApp.sol"; import { BatchOperation, ContextDefinitions, FlowOperatorDefinitions, SuperAppDefinitions, SuperfluidGovernanceConfigs } from "./Definitions.sol"; import { TokenInfo } from "../tokens/TokenInfo.sol"; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { IERC777 } from "@openzeppelin/contracts/token/ERC777/IERC777.sol"; /** * @title Host interface * @author Superfluid * @notice This is the central contract of the system where super agreement, super app * and super token features are connected. * * The Superfluid host contract is also the entry point for the protocol users, * where batch call and meta transaction are provided for UX improvements. * */ interface ISuperfluid { /************************************************************************** * Errors *************************************************************************/ // Superfluid Custom Errors error HOST_AGREEMENT_CALLBACK_IS_NOT_ACTION(); // 0xef4295f6 error HOST_CANNOT_DOWNGRADE_TO_NON_UPGRADEABLE(); // 0x474e7641 error HOST_CALL_AGREEMENT_WITH_CTX_FROM_WRONG_ADDRESS(); // 0x0cd0ebc2 error HOST_CALL_APP_ACTION_WITH_CTX_FROM_WRONG_ADDRESS(); // 0x473f7bd4 error HOST_INVALID_CONFIG_WORD(); // 0xf4c802a4 error HOST_MAX_256_AGREEMENTS(); // 0x7c281a78 error HOST_NON_UPGRADEABLE(); // 0x14f72c9f error HOST_NON_ZERO_LENGTH_PLACEHOLDER_CTX(); // 0x67e9985b error HOST_ONLY_GOVERNANCE(); // 0xc5d22a4e error HOST_UNKNOWN_BATCH_CALL_OPERATION_TYPE(); // 0xb4770115 error HOST_AGREEMENT_ALREADY_REGISTERED(); // 0xdc9ddba8 error HOST_AGREEMENT_IS_NOT_REGISTERED(); // 0x1c9e9bea error HOST_MUST_BE_CONTRACT(); // 0xd4f6b30c error HOST_ONLY_LISTED_AGREEMENT(); // 0x619c5359 // App Related Custom Errors // uses SuperAppDefinitions' App Jail Reasons as _code error APP_RULE(uint256 _code); // 0xa85ba64f error HOST_INVALID_OR_EXPIRED_SUPER_APP_REGISTRATION_KEY(); // 0x19ab84d1 error HOST_NOT_A_SUPER_APP(); // 0x163cbe43 error HOST_NO_APP_REGISTRATION_PERMISSIONS(); // 0x5b93ebf0 error HOST_RECEIVER_IS_NOT_SUPER_APP(); // 0x96aa315e error HOST_SENDER_IS_NOT_SUPER_APP(); // 0xbacfdc40 error HOST_SOURCE_APP_NEEDS_HIGHER_APP_LEVEL(); // 0x44725270 error HOST_SUPER_APP_IS_JAILED(); // 0x02384b64 error HOST_SUPER_APP_ALREADY_REGISTERED(); // 0x01b0a935 error HOST_UNAUTHORIZED_SUPER_APP_FACTORY(); // 0x289533c5 /************************************************************************** * Time * * > The Oracle: You have the sight now, Neo. You are looking at the world without time. * > Neo: Then why can't I see what happens to her? * > The Oracle: We can never see past the choices we don't understand. * > - The Oracle and Neo conversing about the future of Trinity and the effects of Neo's choices *************************************************************************/ function getNow() external view returns (uint256); /************************************************************************** * Governance *************************************************************************/ /** * @dev Get the current governance address of the Superfluid host */ function getGovernance() external view returns(ISuperfluidGovernance governance); /** * @dev Replace the current governance with a new one */ function replaceGovernance(ISuperfluidGovernance newGov) external; /** * @dev Governance replaced event * @param oldGov Address of the old governance contract * @param newGov Address of the new governance contract */ event GovernanceReplaced(ISuperfluidGovernance oldGov, ISuperfluidGovernance newGov); /************************************************************************** * Agreement Whitelisting *************************************************************************/ /** * @dev Register a new agreement class to the system * @param agreementClassLogic Initial agreement class code * * @custom:modifiers * - onlyGovernance */ function registerAgreementClass(ISuperAgreement agreementClassLogic) external; /** * @notice Agreement class registered event * @dev agreementType is the keccak256 hash of: "org.superfluid-finance.agreements.<AGREEMENT_NAME>.<VERSION>" * @param agreementType The agreement type registered * @param code Address of the new agreement */ event AgreementClassRegistered(bytes32 agreementType, address code); /** * @dev Update code of an agreement class * @param agreementClassLogic New code for the agreement class * * @custom:modifiers * - onlyGovernance */ function updateAgreementClass(ISuperAgreement agreementClassLogic) external; /** * @notice Agreement class updated event * @dev agreementType is the keccak256 hash of: "org.superfluid-finance.agreements.<AGREEMENT_NAME>.<VERSION>" * @param agreementType The agreement type updated * @param code Address of the new agreement */ event AgreementClassUpdated(bytes32 agreementType, address code); /** * @notice Check if the agreement type is whitelisted * @dev agreementType is the keccak256 hash of: "org.superfluid-finance.agreements.<AGREEMENT_NAME>.<VERSION>" */ function isAgreementTypeListed(bytes32 agreementType) external view returns(bool yes); /** * @dev Check if the agreement class is whitelisted */ function isAgreementClassListed(ISuperAgreement agreementClass) external view returns(bool yes); /** * @notice Get agreement class * @dev agreementType is the keccak256 hash of: "org.superfluid-finance.agreements.<AGREEMENT_NAME>.<VERSION>" */ function getAgreementClass(bytes32 agreementType) external view returns(ISuperAgreement agreementClass); /** * @dev Map list of the agreement classes using a bitmap * @param bitmap Agreement class bitmap */ function mapAgreementClasses(uint256 bitmap) external view returns (ISuperAgreement[] memory agreementClasses); /** * @notice Create a new bitmask by adding a agreement class to it * @dev agreementType is the keccak256 hash of: "org.superfluid-finance.agreements.<AGREEMENT_NAME>.<VERSION>" * @param bitmap Agreement class bitmap */ function addToAgreementClassesBitmap(uint256 bitmap, bytes32 agreementType) external view returns (uint256 newBitmap); /** * @notice Create a new bitmask by removing a agreement class from it * @dev agreementType is the keccak256 hash of: "org.superfluid-finance.agreements.<AGREEMENT_NAME>.<VERSION>" * @param bitmap Agreement class bitmap */ function removeFromAgreementClassesBitmap(uint256 bitmap, bytes32 agreementType) external view returns (uint256 newBitmap); /************************************************************************** * Super Token Factory **************************************************************************/ /** * @dev Get the super token factory * @return factory The factory */ function getSuperTokenFactory() external view returns (ISuperTokenFactory factory); /** * @dev Get the super token factory logic (applicable to upgradable deployment) * @return logic The factory logic */ function getSuperTokenFactoryLogic() external view returns (address logic); /** * @dev Update super token factory * @param newFactory New factory logic */ function updateSuperTokenFactory(ISuperTokenFactory newFactory) external; /** * @dev SuperToken factory updated event * @param newFactory Address of the new factory */ event SuperTokenFactoryUpdated(ISuperTokenFactory newFactory); /** * @notice Update the super token logic to the latest * @dev Refer to ISuperTokenFactory.Upgradability for expected behaviours */ function updateSuperTokenLogic(ISuperToken token) external; /** * @dev SuperToken logic updated event * @param code Address of the new SuperToken logic */ event SuperTokenLogicUpdated(ISuperToken indexed token, address code); /************************************************************************** * App Registry *************************************************************************/ /** * @dev Message sender (must be a contract) declares itself as a super app. * @custom:deprecated you should use `registerAppWithKey` or `registerAppByFactory` instead, * because app registration is currently governance permissioned on mainnets. * @param configWord The super app manifest configuration, flags are defined in * `SuperAppDefinitions` */ function registerApp(uint256 configWord) external; /** * @dev App registered event * @param app Address of jailed app */ event AppRegistered(ISuperApp indexed app); /** * @dev Message sender declares itself as a super app. * @param configWord The super app manifest configuration, flags are defined in `SuperAppDefinitions` * @param registrationKey The registration key issued by the governance, needed to register on a mainnet. * @notice See https://github.com/superfluid-finance/protocol-monorepo/wiki/Super-App-White-listing-Guide * On testnets or in dev environment, a placeholder (e.g. empty string) can be used. * While the message sender must be the super app itself, the transaction sender (tx.origin) * must be the deployer account the registration key was issued for. */ function registerAppWithKey(uint256 configWord, string calldata registrationKey) external; /** * @dev Message sender (must be a contract) declares app as a super app * @param configWord The super app manifest configuration, flags are defined in `SuperAppDefinitions` * @notice On mainnet deployments, only factory contracts pre-authorized by governance can use this. * See https://github.com/superfluid-finance/protocol-monorepo/wiki/Super-App-White-listing-Guide */ function registerAppByFactory(ISuperApp app, uint256 configWord) external; /** * @dev Query if the app is registered * @param app Super app address */ function isApp(ISuperApp app) external view returns(bool); /** * @dev Query app callbacklevel * @param app Super app address */ function getAppCallbackLevel(ISuperApp app) external view returns(uint8 appCallbackLevel); /** * @dev Get the manifest of the super app * @param app Super app address */ function getAppManifest( ISuperApp app ) external view returns ( bool isSuperApp, bool isJailed, uint256 noopMask ); /** * @dev Query if the app has been jailed * @param app Super app address */ function isAppJailed(ISuperApp app) external view returns (bool isJail); /** * @dev Whitelist the target app for app composition for the source app (msg.sender) * @param targetApp The target super app address */ function allowCompositeApp(ISuperApp targetApp) external; /** * @dev Query if source app is allowed to call the target app as downstream app * @param app Super app address * @param targetApp The target super app address */ function isCompositeAppAllowed( ISuperApp app, ISuperApp targetApp ) external view returns (bool isAppAllowed); /************************************************************************** * Agreement Framework * * Agreements use these function to trigger super app callbacks, updates * app credit and charge gas fees. * * These functions can only be called by registered agreements. *************************************************************************/ /** * @dev (For agreements) StaticCall the app before callback * @param app The super app. * @param callData The call data sending to the super app. * @param isTermination Is it a termination callback? * @param ctx Current ctx, it will be validated. * @return cbdata Data returned from the callback. */ function callAppBeforeCallback( ISuperApp app, bytes calldata callData, bool isTermination, bytes calldata ctx ) external // onlyAgreement // assertValidCtx(ctx) returns(bytes memory cbdata); /** * @dev (For agreements) Call the app after callback * @param app The super app. * @param callData The call data sending to the super app. * @param isTermination Is it a termination callback? * @param ctx Current ctx, it will be validated. * @return newCtx The current context of the transaction. */ function callAppAfterCallback( ISuperApp app, bytes calldata callData, bool isTermination, bytes calldata ctx ) external // onlyAgreement // assertValidCtx(ctx) returns(bytes memory newCtx); /** * @dev (For agreements) Create a new callback stack * @param ctx The current ctx, it will be validated. * @param app The super app. * @param appCreditGranted App credit granted so far. * @param appCreditUsed App credit used so far. * @return newCtx The current context of the transaction. */ function appCallbackPush( bytes calldata ctx, ISuperApp app, uint256 appCreditGranted, int256 appCreditUsed, ISuperfluidToken appCreditToken ) external // onlyAgreement // assertValidCtx(ctx) returns (bytes memory newCtx); /** * @dev (For agreements) Pop from the current app callback stack * @param ctx The ctx that was pushed before the callback stack. * @param appCreditUsedDelta App credit used by the app. * @return newCtx The current context of the transaction. * * @custom:security * - Here we cannot do assertValidCtx(ctx), since we do not really save the stack in memory. * - Hence there is still implicit trust that the agreement handles the callback push/pop pair correctly. */ function appCallbackPop( bytes calldata ctx, int256 appCreditUsedDelta ) external // onlyAgreement returns (bytes memory newCtx); /** * @dev (For agreements) Use app credit. * @param ctx The current ctx, it will be validated. * @param appCreditUsedMore See app credit for more details. * @return newCtx The current context of the transaction. */ function ctxUseCredit( bytes calldata ctx, int256 appCreditUsedMore ) external // onlyAgreement // assertValidCtx(ctx) returns (bytes memory newCtx); /** * @dev (For agreements) Jail the app. * @param app The super app. * @param reason Jail reason code. * @return newCtx The current context of the transaction. */ function jailApp( bytes calldata ctx, ISuperApp app, uint256 reason ) external // onlyAgreement // assertValidCtx(ctx) returns (bytes memory newCtx); /** * @dev Jail event for the app * @param app Address of jailed app * @param reason Reason the app is jailed (see Definitions.sol for the full list) */ event Jail(ISuperApp indexed app, uint256 reason); /************************************************************************** * Contextless Call Proxies * * NOTE: For EOAs or non-app contracts, they are the entry points for interacting * with agreements or apps. * * NOTE: The contextual call data should be generated using * abi.encodeWithSelector. The context parameter should be set to "0x", * an empty bytes array as a placeholder to be replaced by the host * contract. *************************************************************************/ /** * @dev Call agreement function * @param agreementClass The agreement address you are calling * @param callData The contextual call data with placeholder ctx * @param userData Extra user data being sent to the super app callbacks */ function callAgreement( ISuperAgreement agreementClass, bytes calldata callData, bytes calldata userData ) external //cleanCtx //isAgreement(agreementClass) returns(bytes memory returnedData); /** * @notice Call app action * @dev Main use case is calling app action in a batch call via the host * @param callData The contextual call data * * @custom:note See "Contextless Call Proxies" above for more about contextual call data. */ function callAppAction( ISuperApp app, bytes calldata callData ) external //cleanCtx //isAppActive(app) //isValidAppAction(callData) returns(bytes memory returnedData); /************************************************************************** * Contextual Call Proxies and Context Utilities * * For apps, they must use context they receive to interact with * agreements or apps. * * The context changes must be saved and returned by the apps in their * callbacks always, any modification to the context will be detected and * the violating app will be jailed. *************************************************************************/ /** * @dev Context Struct * * @custom:note on backward compatibility: * - Non-dynamic fields are padded to 32bytes and packed * - Dynamic fields are referenced through a 32bytes offset to their "parents" field (or root) * - The order of the fields hence should not be rearranged in order to be backward compatible: * - non-dynamic fields will be parsed at the same memory location, * - and dynamic fields will simply have a greater offset than it was. * - We cannot change the structure of the Context struct because of ABI compatibility requirements */ struct Context { // // Call context // // app callback level uint8 appCallbackLevel; // type of call uint8 callType; // the system timestamp uint256 timestamp; // The intended message sender for the call address msgSender; // // Callback context // // For callbacks it is used to know which agreement function selector is called bytes4 agreementSelector; // User provided data for app callbacks bytes userData; // // App context // // app credit granted uint256 appCreditGranted; // app credit wanted by the app callback uint256 appCreditWantedDeprecated; // app credit used, allowing negative values over a callback session // the appCreditUsed value over a callback sessions is calculated with: // existing flow data owed deposit + sum of the callback agreements // deposit deltas // the final value used to modify the state is determined by the // _adjustNewAppCreditUsed function (in AgreementLibrary.sol) which takes // the appCreditUsed value reached in the callback session and the app // credit granted int256 appCreditUsed; // app address address appAddress; // app credit in super token ISuperfluidToken appCreditToken; } function callAgreementWithContext( ISuperAgreement agreementClass, bytes calldata callData, bytes calldata userData, bytes calldata ctx ) external // requireValidCtx(ctx) // onlyAgreement(agreementClass) returns (bytes memory newCtx, bytes memory returnedData); function callAppActionWithContext( ISuperApp app, bytes calldata callData, bytes calldata ctx ) external // requireValidCtx(ctx) // isAppActive(app) returns (bytes memory newCtx); function decodeCtx(bytes memory ctx) external pure returns (Context memory context); function isCtxValid(bytes calldata ctx) external view returns (bool); /************************************************************************** * Batch call **************************************************************************/ /** * @dev Batch operation data */ struct Operation { // Operation type. Defined in BatchOperation (Definitions.sol) uint32 operationType; // Operation target address target; // Data specific to the operation bytes data; } /** * @dev Batch call function * @param operations Array of batch operations */ function batchCall(Operation[] calldata operations) external; /** * @dev Batch call function for trusted forwarders (EIP-2771) * @param operations Array of batch operations */ function forwardBatchCall(Operation[] calldata operations) external; /************************************************************************** * Function modifiers for access control and parameter validations * * While they cannot be explicitly stated in function definitions, they are * listed in function definition comments instead for clarity. * * TODO: turning these off because solidity-coverage doesn't like it *************************************************************************/ /* /// @dev The current superfluid context is clean. modifier cleanCtx() virtual; /// @dev Require the ctx being valid. modifier requireValidCtx(bytes memory ctx) virtual; /// @dev Assert the ctx being valid. modifier assertValidCtx(bytes memory ctx) virtual; /// @dev The agreement is a listed agreement. modifier isAgreement(ISuperAgreement agreementClass) virtual; // onlyGovernance /// @dev The msg.sender must be a listed agreement. modifier onlyAgreement() virtual; /// @dev The app is registered and not jailed. modifier isAppActive(ISuperApp app) virtual; */ }
/project_/contracts/interfaces/superfluid/ISuperfluidGovernance.sol
// SPDX-License-Identifier: AGPLv3 pragma solidity >= 0.8.4; import { ISuperAgreement } from "./ISuperAgreement.sol"; import { ISuperToken } from "./ISuperToken.sol"; import { ISuperfluidToken } from "./ISuperfluidToken.sol"; import { ISuperfluid } from "./ISuperfluid.sol"; /** * @title Superfluid governance interface * @author Superfluid */ interface ISuperfluidGovernance { /************************************************************************** * Errors *************************************************************************/ error SF_GOV_ARRAYS_NOT_SAME_LENGTH(); // 0x27743aa6 error SF_GOV_INVALID_LIQUIDATION_OR_PATRICIAN_PERIOD(); // 0xe171980a error SF_GOV_MUST_BE_CONTRACT(); // 0x80dddd73 /** * @dev Replace the current governance with a new governance */ function replaceGovernance( ISuperfluid host, address newGov) external; /** * @dev Register a new agreement class */ function registerAgreementClass( ISuperfluid host, address agreementClass) external; /** * @dev Update logics of the contracts * * @custom:note * - Because they might have inter-dependencies, it is good to have one single function to update them all */ function updateContracts( ISuperfluid host, address hostNewLogic, address[] calldata agreementClassNewLogics, address superTokenFactoryNewLogic ) external; /** * @dev Update supertoken logic contract to the latest that is managed by the super token factory */ function batchUpdateSuperTokenLogic( ISuperfluid host, ISuperToken[] calldata tokens) external; /** * @dev Set configuration as address value */ function setConfig( ISuperfluid host, ISuperfluidToken superToken, bytes32 key, address value ) external; /** * @dev Set configuration as uint256 value */ function setConfig( ISuperfluid host, ISuperfluidToken superToken, bytes32 key, uint256 value ) external; /** * @dev Clear configuration */ function clearConfig( ISuperfluid host, ISuperfluidToken superToken, bytes32 key ) external; /** * @dev Get configuration as address value */ function getConfigAsAddress( ISuperfluid host, ISuperfluidToken superToken, bytes32 key) external view returns (address value); /** * @dev Get configuration as uint256 value */ function getConfigAsUint256( ISuperfluid host, ISuperfluidToken superToken, bytes32 key) external view returns (uint256 value); }
/project_/contracts/interfaces/superfluid/ISuperfluidToken.sol
// SPDX-License-Identifier: AGPLv3 pragma solidity >= 0.8.4; import { ISuperAgreement } from "./ISuperAgreement.sol"; /** * @title Superfluid token interface * @author Superfluid */ interface ISuperfluidToken { /************************************************************************** * Errors *************************************************************************/ error SF_TOKEN_AGREEMENT_ALREADY_EXISTS(); // 0xf05521f6 error SF_TOKEN_AGREEMENT_DOES_NOT_EXIST(); // 0xdae18809 error SF_TOKEN_BURN_INSUFFICIENT_BALANCE(); // 0x10ecdf44 error SF_TOKEN_MOVE_INSUFFICIENT_BALANCE(); // 0x2f4cb941 error SF_TOKEN_ONLY_LISTED_AGREEMENT(); // 0xc9ff6644 error SF_TOKEN_ONLY_HOST(); // 0xc51efddd /************************************************************************** * Basic information *************************************************************************/ /** * @dev Get superfluid host contract address */ function getHost() external view returns(address host); /** * @dev Encoded liquidation type data mainly used for handling stack to deep errors * * @custom:note * - version: 1 * - liquidationType key: * - 0 = reward account receives reward (PIC period) * - 1 = liquidator account receives reward (Pleb period) * - 2 = liquidator account receives reward (Pirate period/bailout) */ struct LiquidationTypeData { uint256 version; uint8 liquidationType; } /************************************************************************** * Real-time balance functions *************************************************************************/ /** * @dev Calculate the real balance of a user, taking in consideration all agreements of the account * @param account for the query * @param timestamp Time of balance * @return availableBalance Real-time balance * @return deposit Account deposit * @return owedDeposit Account owed Deposit */ function realtimeBalanceOf( address account, uint256 timestamp ) external view returns ( int256 availableBalance, uint256 deposit, uint256 owedDeposit); /** * @notice Calculate the realtime balance given the current host.getNow() value * @dev realtimeBalanceOf with timestamp equals to block timestamp * @param account for the query * @return availableBalance Real-time balance * @return deposit Account deposit * @return owedDeposit Account owed Deposit */ function realtimeBalanceOfNow( address account ) external view returns ( int256 availableBalance, uint256 deposit, uint256 owedDeposit, uint256 timestamp); /** * @notice Check if account is critical * @dev A critical account is when availableBalance < 0 * @param account The account to check * @param timestamp The time we'd like to check if the account is critical (should use future) * @return isCritical Whether the account is critical */ function isAccountCritical( address account, uint256 timestamp ) external view returns(bool isCritical); /** * @notice Check if account is critical now (current host.getNow()) * @dev A critical account is when availableBalance < 0 * @param account The account to check * @return isCritical Whether the account is critical */ function isAccountCriticalNow( address account ) external view returns(bool isCritical); /** * @notice Check if account is solvent * @dev An account is insolvent when the sum of deposits for a token can't cover the negative availableBalance * @param account The account to check * @param timestamp The time we'd like to check if the account is solvent (should use future) * @return isSolvent True if the account is solvent, false otherwise */ function isAccountSolvent( address account, uint256 timestamp ) external view returns(bool isSolvent); /** * @notice Check if account is solvent now * @dev An account is insolvent when the sum of deposits for a token can't cover the negative availableBalance * @param account The account to check * @return isSolvent True if the account is solvent, false otherwise */ function isAccountSolventNow( address account ) external view returns(bool isSolvent); /** * @notice Get a list of agreements that is active for the account * @dev An active agreement is one that has state for the account * @param account Account to query * @return activeAgreements List of accounts that have non-zero states for the account */ function getAccountActiveAgreements(address account) external view returns(ISuperAgreement[] memory activeAgreements); /************************************************************************** * Super Agreement hosting functions *************************************************************************/ /** * @dev Create a new agreement * @param id Agreement ID * @param data Agreement data */ function createAgreement( bytes32 id, bytes32[] calldata data ) external; /** * @dev Agreement created event * @param agreementClass Contract address of the agreement * @param id Agreement ID * @param data Agreement data */ event AgreementCreated( address indexed agreementClass, bytes32 id, bytes32[] data ); /** * @dev Get data of the agreement * @param agreementClass Contract address of the agreement * @param id Agreement ID * @return data Data of the agreement */ function getAgreementData( address agreementClass, bytes32 id, uint dataLength ) external view returns(bytes32[] memory data); /** * @dev Create a new agreement * @param id Agreement ID * @param data Agreement data */ function updateAgreementData( bytes32 id, bytes32[] calldata data ) external; /** * @dev Agreement updated event * @param agreementClass Contract address of the agreement * @param id Agreement ID * @param data Agreement data */ event AgreementUpdated( address indexed agreementClass, bytes32 id, bytes32[] data ); /** * @dev Close the agreement * @param id Agreement ID */ function terminateAgreement( bytes32 id, uint dataLength ) external; /** * @dev Agreement terminated event * @param agreementClass Contract address of the agreement * @param id Agreement ID */ event AgreementTerminated( address indexed agreementClass, bytes32 id ); /** * @dev Update agreement state slot * @param account Account to be updated * * @custom:note * - To clear the storage out, provide zero-ed array of intended length */ function updateAgreementStateSlot( address account, uint256 slotId, bytes32[] calldata slotData ) external; /** * @dev Agreement account state updated event * @param agreementClass Contract address of the agreement * @param account Account updated * @param slotId slot id of the agreement state */ event AgreementStateUpdated( address indexed agreementClass, address indexed account, uint256 slotId ); /** * @dev Get data of the slot of the state of an agreement * @param agreementClass Contract address of the agreement * @param account Account to query * @param slotId slot id of the state * @param dataLength length of the state data */ function getAgreementStateSlot( address agreementClass, address account, uint256 slotId, uint dataLength ) external view returns (bytes32[] memory slotData); /** * @notice Settle balance from an account by the agreement * @dev The agreement needs to make sure that the balance delta is balanced afterwards * @param account Account to query. * @param delta Amount of balance delta to be settled * * @custom:modifiers * - onlyAgreement */ function settleBalance( address account, int256 delta ) external; /** * @dev Make liquidation payouts (v2) * @param id Agreement ID * @param liquidationTypeData Data regarding the version of the liquidation schema and the type * @param liquidatorAccount Address of the executor of the liquidation * @param useDefaultRewardAccount Whether or not the default reward account receives the rewardAmount * @param targetAccount Account to be liquidated * @param rewardAmount The amount the rewarded account will receive * @param targetAccountBalanceDelta The delta amount the target account balance should change by * * @custom:note * - If a bailout is required (bailoutAmount > 0) * - the actual reward (single deposit) goes to the executor, * - while the reward account becomes the bailout account * - total bailout include: bailout amount + reward amount * - the targetAccount will be bailed out * - If a bailout is not required * - the targetAccount will pay the rewardAmount * - the liquidator (reward account in PIC period) will receive the rewardAmount * * @custom:modifiers * - onlyAgreement */ function makeLiquidationPayoutsV2 ( bytes32 id, bytes memory liquidationTypeData, address liquidatorAccount, bool useDefaultRewardAccount, address targetAccount, uint256 rewardAmount, int256 targetAccountBalanceDelta ) external; /** * @dev Agreement liquidation event v2 (including agent account) * @param agreementClass Contract address of the agreement * @param id Agreement ID * @param liquidatorAccount Address of the executor of the liquidation * @param targetAccount Account of the stream sender * @param rewardAmountReceiver Account that collects the reward or bails out insolvent accounts * @param rewardAmount The amount the reward recipient account balance should change by * @param targetAccountBalanceDelta The amount the sender account balance should change by * @param liquidationTypeData The encoded liquidation type data including the version (how to decode) * * @custom:note * Reward account rule: * - if the agreement is liquidated during the PIC period * - the rewardAmountReceiver will get the rewardAmount (remaining deposit), regardless of the liquidatorAccount * - the targetAccount will pay for the rewardAmount * - if the agreement is liquidated after the PIC period AND the targetAccount is solvent * - the rewardAmountReceiver will get the rewardAmount (remaining deposit) * - the targetAccount will pay for the rewardAmount * - if the targetAccount is insolvent * - the liquidatorAccount will get the rewardAmount (single deposit) * - the default reward account (governance) will pay for both the rewardAmount and bailoutAmount * - the targetAccount will receive the bailoutAmount */ event AgreementLiquidatedV2( address indexed agreementClass, bytes32 id, address indexed liquidatorAccount, address indexed targetAccount, address rewardAmountReceiver, uint256 rewardAmount, int256 targetAccountBalanceDelta, bytes liquidationTypeData ); /************************************************************************** * Function modifiers for access control and parameter validations * * While they cannot be explicitly stated in function definitions, they are * listed in function definition comments instead for clarity. * * NOTE: solidity-coverage not supporting it *************************************************************************/ /// @dev The msg.sender must be host contract //modifier onlyHost() virtual; /// @dev The msg.sender must be a listed agreement. //modifier onlyAgreement() virtual; /************************************************************************** * DEPRECATED *************************************************************************/ /** * @dev Agreement liquidation event (DEPRECATED BY AgreementLiquidatedBy) * @param agreementClass Contract address of the agreement * @param id Agreement ID * @param penaltyAccount Account of the agreement to be penalized * @param rewardAccount Account that collect the reward * @param rewardAmount Amount of liquidation reward * * @custom:deprecated Use AgreementLiquidatedV2 instead */ event AgreementLiquidated( address indexed agreementClass, bytes32 id, address indexed penaltyAccount, address indexed rewardAccount, uint256 rewardAmount ); /** * @dev System bailout occurred (DEPRECATED BY AgreementLiquidatedBy) * @param bailoutAccount Account that bailout the penalty account * @param bailoutAmount Amount of account bailout * * @custom:deprecated Use AgreementLiquidatedV2 instead */ event Bailout( address indexed bailoutAccount, uint256 bailoutAmount ); /** * @dev Agreement liquidation event (DEPRECATED BY AgreementLiquidatedV2) * @param liquidatorAccount Account of the agent that performed the liquidation. * @param agreementClass Contract address of the agreement * @param id Agreement ID * @param penaltyAccount Account of the agreement to be penalized * @param bondAccount Account that collect the reward or bailout accounts * @param rewardAmount Amount of liquidation reward * @param bailoutAmount Amount of liquidation bailouot * * @custom:deprecated Use AgreementLiquidatedV2 instead * * @custom:note * Reward account rule: * - if bailout is equal to 0, then * - the bondAccount will get the rewardAmount, * - the penaltyAccount will pay for the rewardAmount. * - if bailout is larger than 0, then * - the liquidatorAccount will get the rewardAmouont, * - the bondAccount will pay for both the rewardAmount and bailoutAmount, * - the penaltyAccount will pay for the rewardAmount while get the bailoutAmount. */ event AgreementLiquidatedBy( address liquidatorAccount, address indexed agreementClass, bytes32 id, address indexed penaltyAccount, address indexed bondAccount, uint256 rewardAmount, uint256 bailoutAmount ); }
/project_/contracts/interfaces/tokens/ERC20WithTokenInfo.sol
// SPDX-License-Identifier: AGPLv3 pragma solidity >= 0.8.4; import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import { TokenInfo } from "./TokenInfo.sol"; /** * @title ERC20 token with token info interface * @author Superfluid * @dev Using abstract contract instead of interfaces because old solidity * does not support interface inheriting other interfaces * solhint-disable-next-line no-empty-blocks * */ // solhint-disable-next-line no-empty-blocks abstract contract ERC20WithTokenInfo is IERC20, TokenInfo {}
/project_/contracts/interfaces/tokens/TokenInfo.sol
// SPDX-License-Identifier: AGPLv3 pragma solidity >= 0.8.4; /** * @title ERC20 token info interface * @author Superfluid * @dev ERC20 standard interface does not specify these functions, but * often the token implementations have them. */ interface TokenInfo { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() external view returns (string memory); /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5,05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is * called. * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() external view returns (uint8); }
/project_/contracts/interfaces/utils/IRelayRecipient.sol
// SPDX-License-Identifier: AGPLv3 pragma solidity >= 0.8.4; // MODIFIED FROM: https://github.com/opengsn/forwarder/blob/master/contracts/interfaces/IRelayRecipient.sol /** * @title Relay recipient interface * @author Superfluid * @dev A contract must implement this interface in order to support relayed transactions * @dev It is better to inherit the BaseRelayRecipient as its implementation */ interface IRelayRecipient { /** * @notice Returns if the forwarder is trusted to forward relayed transactions to us. * @dev the forwarder is required to verify the sender's signature, and verify * the call is not a replay. */ function isTrustedForwarder(address forwarder) external view returns(bool); /** * @dev EIP 2771 version * * NOTE: * - It is not clear if it is actually from the EIP 2771.... * - https://docs.biconomy.io/guides/enable-gasless-transactions/eip-2771 */ function versionRecipient() external view returns (string memory); }
/project_/contracts/libs/BaseRelayRecipient.sol
// SPDX-License-Identifier: AGPLv3 pragma solidity 0.8.16; import "../interfaces/utils/IRelayRecipient.sol"; /** * @title Base relay recipient contract * @author Superfluid * @dev A base contract to be inherited by any contract that want to receive relayed transactions * A subclass must use "_msgSender()" instead of "msg.sender" * MODIFIED FROM: https://github.com/opengsn/forwarder/blob/master/contracts/BaseRelayRecipient.sol */ abstract contract BaseRelayRecipient is IRelayRecipient { /** * @dev Check if the forwarder is trusted */ function isTrustedForwarder(address forwarder) public view virtual override returns(bool); /** * @dev Return the transaction signer of this call * * if the call came through our trusted forwarder, return the original sender. * otherwise, return `msg.sender`. * should be used in the contract anywhere instead of msg.sender */ function _getTransactionSigner() internal virtual view returns (address payable ret) { require(msg.data.length >= 24 && isTrustedForwarder(msg.sender), "Not trusted forwarder"); // At this point we know that the sender is a trusted forwarder, // so we trust that the last bytes of msg.data are the verified sender address. // extract sender address from the end of msg.data assembly { ret := shr(96,calldataload(sub(calldatasize(),20))) } } }
/project_/contracts/libs/CallUtils.sol
// SPDX-License-Identifier: AGPLv3 pragma solidity 0.8.16; /** * @title Call utilities library that is absent from the OpenZeppelin * @author Superfluid */ library CallUtils { /// @dev Bubble up the revert from the returnedData (supports Panic, Error & Custom Errors) /// @notice This is needed in order to provide some human-readable revert message from a call /// @param returnedData Response of the call function revertFromReturnedData(bytes memory returnedData) internal pure { if (returnedData.length < 4) { // case 1: catch all revert("CallUtils: target revert()"); } else { bytes4 errorSelector; assembly { errorSelector := mload(add(returnedData, 0x20)) } if (errorSelector == bytes4(0x4e487b71) /* `seth sig "Panic(uint256)"` */) { // case 2: Panic(uint256) (Defined since 0.8.0) // solhint-disable-next-line max-line-length // ref: https://docs.soliditylang.org/en/v0.8.0/control-structures.html#panic-via-assert-and-error-via-require) string memory reason = "CallUtils: target panicked: 0x__"; uint errorCode; assembly { errorCode := mload(add(returnedData, 0x24)) let reasonWord := mload(add(reason, 0x20)) // [0..9] is converted to ['0'..'9'] // [0xa..0xf] is not correctly converted to ['a'..'f'] // but since panic code doesn't have those cases, we will ignore them for now! let e1 := add(and(errorCode, 0xf), 0x30) let e2 := shl(8, add(shr(4, and(errorCode, 0xf0)), 0x30)) reasonWord := or( and(reasonWord, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000), or(e2, e1)) mstore(add(reason, 0x20), reasonWord) } revert(reason); } else { // case 3: Error(string) (Defined at least since 0.7.0) // case 4: Custom errors (Defined since 0.8.0) uint len = returnedData.length; assembly { revert(add(returnedData, 32), len) } } } } /** * @dev Helper method to parse data and extract the method signature (selector). * * Copied from: https://github.com/argentlabs/argent-contracts/ * blob/master/contracts/modules/common/Utils.sol#L54-L60 */ function parseSelector(bytes memory callData) internal pure returns (bytes4 selector) { require(callData.length >= 4, "CallUtils: invalid callData"); // solhint-disable-next-line no-inline-assembly assembly { selector := mload(add(callData, 0x20)) } } /** * @dev Pad length to 32 bytes word boundary */ function padLength32(uint256 len) internal pure returns (uint256 paddedLen) { return ((len / 32) + (((len & 31) > 0) /* rounding? */ ? 1 : 0)) * 32; } /** * @dev Validate if the data is encoded correctly with abi.encode(bytesData) * * Expected ABI Encode Layout: * | word 1 | word 2 | word 3 | the rest... * | data length | bytesData offset | bytesData length | bytesData + padLength32 zeros | */ function isValidAbiEncodedBytes(bytes memory data) internal pure returns (bool) { if (data.length < 64) return false; uint bytesOffset; uint bytesLen; // bytes offset is always expected to be 32 assembly { bytesOffset := mload(add(data, 32)) } if (bytesOffset != 32) return false; assembly { bytesLen := mload(add(data, 64)) } // the data length should be bytesData.length + 64 + padded bytes length return data.length == 64 + padLength32(bytesLen); } }
/project_/contracts/upgradability/UUPSProxiable.sol
// SPDX-License-Identifier: AGPLv3 pragma solidity 0.8.16; import { UUPSUtils } from "./UUPSUtils.sol"; import { Initializable } from "@openzeppelin/contracts/proxy/utils/Initializable.sol"; /** * @title UUPS (Universal Upgradeable Proxy Standard) Proxiable contract. */ abstract contract UUPSProxiable is Initializable { /** * @dev Get current implementation code address. */ function getCodeAddress() public view returns (address codeAddress) { return UUPSUtils.implementation(); } function updateCode(address newAddress) external virtual; // allows to mark logic contracts as initialized in order to reduce the attack surface // solhint-disable-next-line no-empty-blocks function castrate() external initializer { } /** * @dev Proxiable UUID marker function, this would help to avoid wrong logic * contract to be used for upgrading. * * NOTE: The semantics of the UUID deviates from the actual UUPS standard, * where it is equivalent of _IMPLEMENTATION_SLOT. */ function proxiableUUID() public view virtual returns (bytes32); /** * @dev Update code address function. * It is internal, so the derived contract could setup its own permission logic. */ function _updateCodeAddress(address newAddress) internal { // require UUPSProxy.initializeProxy first require(UUPSUtils.implementation() != address(0), "UUPSProxiable: not upgradable"); require( proxiableUUID() == UUPSProxiable(newAddress).proxiableUUID(), "UUPSProxiable: not compatible logic" ); require( address(this) != newAddress, "UUPSProxiable: proxy loop" ); UUPSUtils.setImplementation(newAddress); emit CodeUpdated(proxiableUUID(), newAddress); } event CodeUpdated(bytes32 uuid, address codeAddress); }
/project_/contracts/upgradability/UUPSProxy.sol
// SPDX-License-Identifier: AGPLv3 pragma solidity 0.8.16; import { UUPSUtils } from "./UUPSUtils.sol"; import { Proxy } from "@openzeppelin/contracts/proxy/Proxy.sol"; /** * @title UUPS (Universal Upgradeable Proxy Standard) Proxy * * NOTE: * - Compliant with [Universal Upgradeable Proxy Standard](https://eips.ethereum.org/EIPS/eip-1822) * - Compiiant with [Standard Proxy Storage Slots](https://eips.ethereum.org/EIPS/eip-1967) * - Implements delegation of calls to other contracts, with proper forwarding of * return values and bubbling of failures. * - It defines a fallback function that delegates all calls to the implementation. */ contract UUPSProxy is Proxy { /** * @dev Proxy initialization function. * This should only be called once and it is permission-less. * @param initialAddress Initial logic contract code address to be used. */ function initializeProxy(address initialAddress) external { require(initialAddress != address(0), "UUPSProxy: zero address"); require(UUPSUtils.implementation() == address(0), "UUPSProxy: already initialized"); UUPSUtils.setImplementation(initialAddress); } /// @dev Proxy._implementation implementation function _implementation() internal virtual override view returns (address) { return UUPSUtils.implementation(); } }
/project_/contracts/upgradability/UUPSUtils.sol
// SPDX-License-Identifier: AGPLv3 pragma solidity 0.8.16; /** * @title UUPS (Universal Upgradeable Proxy Standard) Shared Library */ library UUPSUtils { /** * @dev Implementation slot constant. * Using https://eips.ethereum.org/EIPS/eip-1967 standard * Storage slot 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc * (obtained as bytes32(uint256(keccak256('eip1967.proxy.implementation')) - 1)). */ bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /// @dev Get implementation address. function implementation() internal view returns (address impl) { assembly { // solium-disable-line impl := sload(_IMPLEMENTATION_SLOT) } } /// @dev Set new implementation address. function setImplementation(address codeAddress) internal { assembly { // solium-disable-line sstore( _IMPLEMENTATION_SLOT, codeAddress ) } } }
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"bool","name":"nonUpgradable","internalType":"bool"},{"type":"bool","name":"appWhiteListingEnabled","internalType":"bool"}]},{"type":"error","name":"APP_RULE","inputs":[{"type":"uint256","name":"_code","internalType":"uint256"}]},{"type":"error","name":"HOST_AGREEMENT_ALREADY_REGISTERED","inputs":[]},{"type":"error","name":"HOST_AGREEMENT_CALLBACK_IS_NOT_ACTION","inputs":[]},{"type":"error","name":"HOST_AGREEMENT_IS_NOT_REGISTERED","inputs":[]},{"type":"error","name":"HOST_CALL_AGREEMENT_WITH_CTX_FROM_WRONG_ADDRESS","inputs":[]},{"type":"error","name":"HOST_CALL_APP_ACTION_WITH_CTX_FROM_WRONG_ADDRESS","inputs":[]},{"type":"error","name":"HOST_CANNOT_DOWNGRADE_TO_NON_UPGRADEABLE","inputs":[]},{"type":"error","name":"HOST_INVALID_CONFIG_WORD","inputs":[]},{"type":"error","name":"HOST_INVALID_OR_EXPIRED_SUPER_APP_REGISTRATION_KEY","inputs":[]},{"type":"error","name":"HOST_MAX_256_AGREEMENTS","inputs":[]},{"type":"error","name":"HOST_MUST_BE_CONTRACT","inputs":[]},{"type":"error","name":"HOST_NON_UPGRADEABLE","inputs":[]},{"type":"error","name":"HOST_NON_ZERO_LENGTH_PLACEHOLDER_CTX","inputs":[]},{"type":"error","name":"HOST_NOT_A_SUPER_APP","inputs":[]},{"type":"error","name":"HOST_NO_APP_REGISTRATION_PERMISSIONS","inputs":[]},{"type":"error","name":"HOST_ONLY_GOVERNANCE","inputs":[]},{"type":"error","name":"HOST_ONLY_LISTED_AGREEMENT","inputs":[]},{"type":"error","name":"HOST_RECEIVER_IS_NOT_SUPER_APP","inputs":[]},{"type":"error","name":"HOST_SENDER_IS_NOT_SUPER_APP","inputs":[]},{"type":"error","name":"HOST_SOURCE_APP_NEEDS_HIGHER_APP_LEVEL","inputs":[]},{"type":"error","name":"HOST_SUPER_APP_ALREADY_REGISTERED","inputs":[]},{"type":"error","name":"HOST_SUPER_APP_IS_JAILED","inputs":[]},{"type":"error","name":"HOST_UNAUTHORIZED_SUPER_APP_FACTORY","inputs":[]},{"type":"error","name":"HOST_UNKNOWN_BATCH_CALL_OPERATION_TYPE","inputs":[]},{"type":"event","name":"AgreementClassRegistered","inputs":[{"type":"bytes32","name":"agreementType","internalType":"bytes32","indexed":false},{"type":"address","name":"code","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"AgreementClassUpdated","inputs":[{"type":"bytes32","name":"agreementType","internalType":"bytes32","indexed":false},{"type":"address","name":"code","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"AppRegistered","inputs":[{"type":"address","name":"app","internalType":"contract ISuperApp","indexed":true}],"anonymous":false},{"type":"event","name":"CodeUpdated","inputs":[{"type":"bytes32","name":"uuid","internalType":"bytes32","indexed":false},{"type":"address","name":"codeAddress","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"GovernanceReplaced","inputs":[{"type":"address","name":"oldGov","internalType":"contract ISuperfluidGovernance","indexed":false},{"type":"address","name":"newGov","internalType":"contract ISuperfluidGovernance","indexed":false}],"anonymous":false},{"type":"event","name":"Initialized","inputs":[{"type":"uint8","name":"version","internalType":"uint8","indexed":false}],"anonymous":false},{"type":"event","name":"Jail","inputs":[{"type":"address","name":"app","internalType":"contract ISuperApp","indexed":true},{"type":"uint256","name":"reason","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"SuperTokenFactoryUpdated","inputs":[{"type":"address","name":"newFactory","internalType":"contract ISuperTokenFactory","indexed":false}],"anonymous":false},{"type":"event","name":"SuperTokenLogicUpdated","inputs":[{"type":"address","name":"token","internalType":"contract ISuperToken","indexed":true},{"type":"address","name":"code","internalType":"address","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"APP_WHITE_LISTING_ENABLED","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint64","name":"","internalType":"uint64"}],"name":"CALLBACK_GAS_LIMIT","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"NON_UPGRADABLE_DEPLOYMENT","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"newBitmap","internalType":"uint256"}],"name":"addToAgreementClassesBitmap","inputs":[{"type":"uint256","name":"bitmap","internalType":"uint256"},{"type":"bytes32","name":"agreementType","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"allowCompositeApp","inputs":[{"type":"address","name":"targetApp","internalType":"contract ISuperApp"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bytes","name":"newCtx","internalType":"bytes"}],"name":"appCallbackPop","inputs":[{"type":"bytes","name":"ctx","internalType":"bytes"},{"type":"int256","name":"appCreditUsedDelta","internalType":"int256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bytes","name":"appCtx","internalType":"bytes"}],"name":"appCallbackPush","inputs":[{"type":"bytes","name":"ctx","internalType":"bytes"},{"type":"address","name":"app","internalType":"contract ISuperApp"},{"type":"uint256","name":"appCreditGranted","internalType":"uint256"},{"type":"int256","name":"appCreditUsed","internalType":"int256"},{"type":"address","name":"appCreditToken","internalType":"contract ISuperfluidToken"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"batchCall","inputs":[{"type":"tuple[]","name":"operations","internalType":"struct ISuperfluid.Operation[]","components":[{"type":"uint32","name":"operationType","internalType":"uint32"},{"type":"address","name":"target","internalType":"address"},{"type":"bytes","name":"data","internalType":"bytes"}]}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bytes","name":"returnedData","internalType":"bytes"}],"name":"callAgreement","inputs":[{"type":"address","name":"agreementClass","internalType":"contract ISuperAgreement"},{"type":"bytes","name":"callData","internalType":"bytes"},{"type":"bytes","name":"userData","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bytes","name":"newCtx","internalType":"bytes"},{"type":"bytes","name":"returnedData","internalType":"bytes"}],"name":"callAgreementWithContext","inputs":[{"type":"address","name":"agreementClass","internalType":"contract ISuperAgreement"},{"type":"bytes","name":"callData","internalType":"bytes"},{"type":"bytes","name":"userData","internalType":"bytes"},{"type":"bytes","name":"ctx","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bytes","name":"returnedData","internalType":"bytes"}],"name":"callAppAction","inputs":[{"type":"address","name":"app","internalType":"contract ISuperApp"},{"type":"bytes","name":"callData","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bytes","name":"newCtx","internalType":"bytes"}],"name":"callAppActionWithContext","inputs":[{"type":"address","name":"app","internalType":"contract ISuperApp"},{"type":"bytes","name":"callData","internalType":"bytes"},{"type":"bytes","name":"ctx","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bytes","name":"newCtx","internalType":"bytes"}],"name":"callAppAfterCallback","inputs":[{"type":"address","name":"app","internalType":"contract ISuperApp"},{"type":"bytes","name":"callData","internalType":"bytes"},{"type":"bool","name":"isTermination","internalType":"bool"},{"type":"bytes","name":"ctx","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bytes","name":"cbdata","internalType":"bytes"}],"name":"callAppBeforeCallback","inputs":[{"type":"address","name":"app","internalType":"contract ISuperApp"},{"type":"bytes","name":"callData","internalType":"bytes"},{"type":"bool","name":"isTermination","internalType":"bool"},{"type":"bytes","name":"ctx","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"castrate","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bytes","name":"newCtx","internalType":"bytes"}],"name":"ctxUseCredit","inputs":[{"type":"bytes","name":"ctx","internalType":"bytes"},{"type":"int256","name":"appCreditUsedMore","internalType":"int256"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"tuple","name":"context","internalType":"struct ISuperfluid.Context","components":[{"type":"uint8","name":"appCallbackLevel","internalType":"uint8"},{"type":"uint8","name":"callType","internalType":"uint8"},{"type":"uint256","name":"timestamp","internalType":"uint256"},{"type":"address","name":"msgSender","internalType":"address"},{"type":"bytes4","name":"agreementSelector","internalType":"bytes4"},{"type":"bytes","name":"userData","internalType":"bytes"},{"type":"uint256","name":"appCreditGranted","internalType":"uint256"},{"type":"uint256","name":"appCreditWantedDeprecated","internalType":"uint256"},{"type":"int256","name":"appCreditUsed","internalType":"int256"},{"type":"address","name":"appAddress","internalType":"address"},{"type":"address","name":"appCreditToken","internalType":"contract ISuperfluidToken"}]}],"name":"decodeCtx","inputs":[{"type":"bytes","name":"ctx","internalType":"bytes"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"forwardBatchCall","inputs":[{"type":"tuple[]","name":"operations","internalType":"struct ISuperfluid.Operation[]","components":[{"type":"uint32","name":"operationType","internalType":"uint32"},{"type":"address","name":"target","internalType":"address"},{"type":"bytes","name":"data","internalType":"bytes"}]}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"agreementClass","internalType":"contract ISuperAgreement"}],"name":"getAgreementClass","inputs":[{"type":"bytes32","name":"agreementType","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint8","name":"","internalType":"uint8"}],"name":"getAppCallbackLevel","inputs":[{"type":"address","name":"appAddr","internalType":"contract ISuperApp"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"isSuperApp","internalType":"bool"},{"type":"bool","name":"isJailed","internalType":"bool"},{"type":"uint256","name":"noopMask","internalType":"uint256"}],"name":"getAppManifest","inputs":[{"type":"address","name":"app","internalType":"contract ISuperApp"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"codeAddress","internalType":"address"}],"name":"getCodeAddress","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract ISuperfluidGovernance"}],"name":"getGovernance","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"getNow","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"factory","internalType":"contract ISuperTokenFactory"}],"name":"getSuperTokenFactory","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"logic","internalType":"address"}],"name":"getSuperTokenFactoryLogic","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"initialize","inputs":[{"type":"address","name":"gov","internalType":"contract ISuperfluidGovernance"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"yes","internalType":"bool"}],"name":"isAgreementClassListed","inputs":[{"type":"address","name":"agreementClass","internalType":"contract ISuperAgreement"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"yes","internalType":"bool"}],"name":"isAgreementTypeListed","inputs":[{"type":"bytes32","name":"agreementType","internalType":"bytes32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isApp","inputs":[{"type":"address","name":"app","internalType":"contract ISuperApp"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isAppJailed","inputs":[{"type":"address","name":"app","internalType":"contract ISuperApp"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isCompositeAppAllowed","inputs":[{"type":"address","name":"app","internalType":"contract ISuperApp"},{"type":"address","name":"targetApp","internalType":"contract ISuperApp"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isCtxValid","inputs":[{"type":"bytes","name":"ctx","internalType":"bytes"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"isTrustedForwarder","inputs":[{"type":"address","name":"forwarder","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"bytes","name":"newCtx","internalType":"bytes"}],"name":"jailApp","inputs":[{"type":"bytes","name":"ctx","internalType":"bytes"},{"type":"address","name":"app","internalType":"contract ISuperApp"},{"type":"uint256","name":"reason","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address[]","name":"agreementClasses","internalType":"contract ISuperAgreement[]"}],"name":"mapAgreementClasses","inputs":[{"type":"uint256","name":"bitmap","internalType":"uint256"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"bytes32","name":"","internalType":"bytes32"}],"name":"proxiableUUID","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"registerAgreementClass","inputs":[{"type":"address","name":"agreementClassLogic","internalType":"contract ISuperAgreement"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"registerApp","inputs":[{"type":"uint256","name":"configWord","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"registerAppByFactory","inputs":[{"type":"address","name":"app","internalType":"contract ISuperApp"},{"type":"uint256","name":"configWord","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"registerAppWithKey","inputs":[{"type":"uint256","name":"configWord","internalType":"uint256"},{"type":"string","name":"registrationKey","internalType":"string"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"newBitmap","internalType":"uint256"}],"name":"removeFromAgreementClassesBitmap","inputs":[{"type":"uint256","name":"bitmap","internalType":"uint256"},{"type":"bytes32","name":"agreementType","internalType":"bytes32"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"replaceGovernance","inputs":[{"type":"address","name":"newGov","internalType":"contract ISuperfluidGovernance"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateAgreementClass","inputs":[{"type":"address","name":"agreementClassLogic","internalType":"contract ISuperAgreement"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateCode","inputs":[{"type":"address","name":"newAddress","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateSuperTokenFactory","inputs":[{"type":"address","name":"newFactory","internalType":"contract ISuperTokenFactory"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"updateSuperTokenLogic","inputs":[{"type":"address","name":"token","internalType":"contract ISuperToken"}]},{"type":"function","stateMutability":"pure","outputs":[{"type":"string","name":"","internalType":"string"}],"name":"versionRecipient","inputs":[]}]
Contract Creation Code
0x60c06040523480156200001157600080fd5b5060405162004f1b38038062004f1b83398101604081905262000034916200005b565b901515608052151560a05262000093565b805180151581146200005657600080fd5b919050565b600080604083850312156200006f57600080fd5b6200007a8362000045565b91506200008a6020840162000045565b90509250929050565b60805160a051614e23620000f86000396000818161058801528181611d870152818161225a015261266e0152600081816106bc0152818161077e01528181610a0f0152818161103701528181611172015281816112d1015261259c0152614e236000f3fe608060405234801561001057600080fd5b50600436106102a05760003560e01c8063768fabb011610167578063bb84cfa1116100ce578063c56a069d11610087578063c56a069d14610697578063cd312ec4146106b7578063e8dccb7d146106de578063f2e55caf14610700578063f373305214610708578063f9f522f41461071b57600080fd5b8063bb84cfa114610609578063bbe4fd5014610645578063bced3ddc1461064b578063bd1c448b1461065e578063bf42873414610671578063c4d66de81461068457600080fd5b80639d297e30116101205780639d297e3014610583578063a5dbbbcd146105aa578063ad3915c8146105bd578063b6d200de146105d0578063b724211e146105e3578063ba48b5f8146105f657600080fd5b8063768fabb01461050a578063787afde71461051d5780638ca48484146105305780639378fa1314610543578063989b0c3e146105685780639903ad381461057b57600080fd5b806350d75d251161020b578063670e77e3116101c4578063670e77e31461049a5780636ad3ca7d146104ad5780636b4f3335146104c05780637283100c146104d3578063731aed6e146104e657806374041e02146104f757600080fd5b806350d75d251461041657806352d1902d1461041e57806354fbc4931461044e57806357121e0c14610461578063572b6c051461047457806359a291411461048757600080fd5b806339255d5b1161025d57806339255d5b146103565780633ca3ad4e146103695780633f6c923a146103a45780634329d293146103c457806346951954146103e5578063486ff0cd146103f857600080fd5b806306cecba8146102a557806315a024e1146102ba5780631e6d0a84146102cd5780631e855cf3146102f6578063289b3c0d1461030957806333d608f114610334575b600080fd5b6102b86102b3366004613d6b565b61074b565b005b6102b86102c8366004613d6b565b610922565b6102e06102db366004613de5565b610b72565b6040516102ed9190613ecb565b60405180910390f35b6102e0610304366004613fa1565b610dbe565b6000546201000090046001600160a01b03165b6040516001600160a01b0390911681526020016102ed565b61033e622dc6c081565b6040516001600160401b0390911681526020016102ed565b6102e0610364366004613ff0565b610dd4565b610394610377366004613d6b565b6001600160a01b0316600090815260046020526040902054151590565b60405190151581526020016102ed565b6103b76103b2366004614065565b610dea565b6040516102ed9190614099565b6103d76103d236600461417a565b610dfb565b6040516102ed929190614226565b6102b86103f3366004613d6b565b611004565b604080518082019091526002815261763160f01b60208201526102e0565b61031c611100565b7fcd355cae2c435f8c5e0c626c4691d22fd85aa7422a424c6f0bced6e64c7aba745b6040519081526020016102ed565b6102b861045c366004613d6b565b61112f565b6102b861046f366004613d6b565b6113b2565b610394610482366004613d6b565b611480565b6102e061049536600461424b565b61150a565b6102b86104a8366004614296565b6115ec565b6102b86104bb366004614296565b611602565b6103946104ce366004613d6b565b61160d565b6102b86104e1366004613d6b565b611631565b6003546001600160a01b031661031c565b6102e0610505366004613de5565b6116d9565b6102e061051836600461430a565b611828565b6102b861052b366004613d6b565b6119c4565b61039461053e366004613d6b565b611b07565b610556610551366004613d6b565b611bcc565b60405160ff90911681526020016102ed565b6102e061057636600461424b565b611bed565b6102b8611c80565b6103947f000000000000000000000000000000000000000000000000000000000000000081565b6104406105b8366004614385565b611d3b565b6102b86105cb3660046143a7565b611d85565b61031c6105de3660046143a7565b611dd0565b6102e06105f13660046143c0565b611e37565b6102e061060436600461441c565b611ef8565b61039461061736600461449e565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b42610440565b610440610659366004614385565b61220f565b6102b861066c3660046144d7565b612258565b61039461067f366004614522565b612370565b6102b8610692366004613d6b565b6123b1565b6106aa6106a53660046143a7565b612495565b6040516102ed9190614563565b6103947f000000000000000000000000000000000000000000000000000000000000000081565b6103946106ec3660046143a7565b600090815260026020526040902054151590565b61031c61257f565b6102b86107163660046145b0565b612647565b61072e610729366004613d6b565b61274f565b6040805193151584529115156020840152908201526060016102ed565b6000546201000090046001600160a01b0316331461077c576040516362e9152760e11b815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000156107bb576040516314f72c9f60e01b815260040160405180910390fd5b6000816001600160a01b0316637730599e6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061081f91906145dc565b60008181526002602052604081205491925081900361085157604051630e4f4df560e11b815260040160405180910390fd5b6000600161085f818461460b565b8154811061086f5761086f61461e565b6000918252602090912001546040516311a5465560e21b81526001600160a01b03868116600483015290911691508190634695195490602401600060405180830381600087803b1580156108c257600080fd5b505af11580156108d6573d6000803e3d6000fd5b5050604080518681526001600160a01b03881660208201527f9279aa773f2b588996032d8de89911555039f28b13a11a7c17074330bc082d9a935001905060405180910390a150505050565b6000546201000090046001600160a01b03163314610953576040516362e9152760e11b815260040160405180910390fd5b6000816001600160a01b0316637730599e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610993573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109b791906145dc565b600081815260026020526040902054909150156109e757604051631b93bb7560e31b815260040160405180910390fd5b60015461010011610a0b57604051630f85034f60e31b815260040160405180910390fd5b60007f0000000000000000000000000000000000000000000000000000000000000000610ac5576000604051610a4090613cee565b604051809103906000f080158015610a5c573d6000803e3d6000fd5b50604051634a0687ef60e01b81526001600160a01b03868116600483015291925090821690634a0687ef90602401600060405180830381600087803b158015610aa457600080fd5b505af1158015610ab8573d6000803e3d6000fd5b5050505080915050610ac8565b50815b6001805480820182557fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180546001600160a01b0384166001600160a01b0319909116179055546000838152600260205260409081902091909155517f878135063a6cfb3bc333e534b1fdc83f4f12221cad6705c31c0567048a8bd3d190610b6590849086909182526001600160a01b0316602082015260400190565b60405180910390a1505050565b6060610b7d33611b07565b610b9a5760405163619c535960e01b815260040160405180910390fd5b82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610bdc925083915061279e9050565b610be857610be8614634565b600080610c628a6000898c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8f018190048102820181019092528d815292508d91508c90819084018382808284376000920191909152506127be92505050565b915091508115610d7757610c758161294b565b15610d0f5780806020019051810190610c8e919061468f565b9350610c998461279e565b610d0a5786610cc35760405163a85ba64f60e01b8152601460048201526024015b60405180910390fd5b85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929650610d0a92508c91506014905061299f565b610db1565b86610d305760405163a85ba64f60e01b815260166004820152602401610cba565b85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929650610d0a92508c91506016905061299f565b85858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509296505050505b5050509695505050505050565b6060610dcb338484612a14565b90505b92915050565b6060610de233858585612c4f565b949350505050565b610df2613cfb565b610dce82612d5e565b60608083838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610e40925083915061279e9050565b610e605760405163a85ba64f60e01b815260146004820152602401610cba565b89610e6a81611b07565b610e875760405163619c535960e01b815260040160405180910390fd5b6000610ec887878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610dea92505050565b6101208101519091506001600160a01b03163314610ef95760405163066875e160e11b815260040160405180910390fd5b60608101805133909152604080516020601f8c018190048102820181019092528a8152908b908b908190840183828082843760009201919091525050505060a0830152610f4582612e29565b95506000610f8b8e8e8e8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c9250612f5d915050565b965090508015610fea5785806020019051810190610fa9919061468f565b9650610fb48761279e565b610fc057610fc0614634565b610fc987610dea565b6001600160a01b03831660608201529250610fe383612e29565b9650610ff3565b610ff386613016565b505050505097509795505050505050565b6000546201000090046001600160a01b03163314611035576040516362e9152760e11b815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000015611074576040516314f72c9f60e01b815260040160405180910390fd5b806001600160a01b031663cd312ec46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110d691906146c3565b156110f45760405163474e764160e01b815260040160405180910390fd5b6110fd81613121565b50565b600061112a7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905090565b6000546201000090046001600160a01b03163314611160576040516362e9152760e11b815260040160405180910390fd5b6003546001600160a01b03166112cf577f00000000000000000000000000000000000000000000000000000000000000006112465760006040516111a390613cee565b604051809103906000f0801580156111bf573d6000803e3d6000fd5b50604051634a0687ef60e01b81526001600160a01b03848116600483015291925090821690634a0687ef90602401600060405180830381600087803b15801561120757600080fd5b505af115801561121b573d6000803e3d6000fd5b5050600380546001600160a01b0319166001600160a01b039490941693909317909255506112629050565b600380546001600160a01b0319166001600160a01b0383161790555b600360009054906101000a90046001600160a01b03166001600160a01b0316638129fc1c6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156112b257600080fd5b505af11580156112c6573d6000803e3d6000fd5b5050505061136e565b7f00000000000000000000000000000000000000000000000000000000000000001561130e576040516314f72c9f60e01b815260040160405180910390fd5b6003546040516311a5465560e21b81526001600160a01b03838116600483015290911690634695195490602401600060405180830381600087803b15801561135557600080fd5b505af1158015611369573d6000803e3d6000fd5b505050505b6003546040516001600160a01b0390911681527fce13a9895a1719ad4493b2ac1a9bfb36070566161abab408e7ecbe586da8d499906020015b60405180910390a150565b336000818152600460205260409020546113df576040516302eb3f7160e61b815260040160405180910390fd5b6001600160a01b03821660009081526004602052604090205461141557604051634b5518af60e11b815260040160405180910390fd5b61141e82611bcc565b60ff1661142a82611bcc565b60ff161161144b57604051630447252760e41b815260040160405180910390fd5b6001600160a01b039081166000908152600560209081526040808320949093168252929092529020805460ff19166001179055565b600080546201000090046001600160a01b03166380f70cba30836114a38661335b565b6040518463ffffffff1660e01b81526004016114c1939291906146e0565b602060405180830381865afa1580156114de573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061150291906145dc565b151592915050565b606061151533611b07565b6115325760405163619c535960e01b815260040160405180910390fd5b83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611574925083915061279e9050565b61158057611580614634565b60006115c186868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610dea92505050565b90508381610100018181516115d69190614704565b9052506115e281612e29565b9695505050505050565b6115fe6115f76133e3565b838361344b565b5050565b6115fe33838361344b565b6001600160a01b038116600090815260046020526040812054618000161515610dce565b6000546201000090046001600160a01b03163314611662576040516362e9152760e11b815260040160405180910390fd5b600054604080516001600160a01b03620100009093048316815291831660208301527f13abda02e63c790d0e2818b251282cfe5cbe0a8abd69c54bf5d2260c0907bd2e910160405180910390a1600080546001600160a01b03909216620100000262010000600160b01b0319909216919091179055565b60606116e433611b07565b6117015760405163619c535960e01b815260040160405180910390fd5b82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611743925083915061279e9050565b61174f5761174f614634565b6000806117c98a6001898c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8f018190048102820181019092528d815292508d91508c90819084018382808284376000920191909152506127be92505050565b915091508115610db1576117dc8161294b565b156117fc57808060200190518101906117f5919061468f565b9350610db1565b8661181d5760405163a85ba64f60e01b815260166004820152602401610cba565b610db18a601661299f565b606061183333611b07565b6118505760405163619c535960e01b815260040160405180910390fd5b86868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611892925083915061279e9050565b61189e5761189e614634565b60006118df89898080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610dea92505050565b905061190681606001516001600160a01b0316600090815260046020526040902054151590565b801561191a57506001816000015160ff1610155b1561196d5760608101516001600160a01b039081166000908152600560209081526040808320938b168352929052205460ff1661196d5760405163a85ba64f60e01b8152601e6004820152602401610cba565b8051816119798261472c565b60ff169052506003602082015260c0810186905261010081018590526001600160a01b0380881661012083015284166101408201526119b781612e29565b9998505050505050505050565b6000546201000090046001600160a01b031633146119f5576040516362e9152760e11b815260040160405180910390fd5b60035460408051634a3852d960e11b815290516000926001600160a01b031691639470a5b29160048083019260209291908290030181865afa158015611a3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a63919061474b565b6040516311a5465560e21b81526001600160a01b03808316600483015291925090831690634695195490602401600060405180830381600087803b158015611aaa57600080fd5b505af1158015611abe573d6000803e3d6000fd5b50506040516001600160a01b038481168252851692507f840acbd291b38534819f47f875839277e502f40e1c7bfea2c5fc2c8017442cd391506020015b60405180910390a25050565b600080826001600160a01b0316637730599e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b6c91906145dc565b6000818152600260205260409020549091508015801590610de257506001600160a01b0384166001611b9e818461460b565b81548110611bae57611bae61461e565b6000918252602090912001546001600160a01b031614949350505050565b6001600160a01b03811660009081526004602052604081205460ff16610dce565b6060611bf833611b07565b611c155760405163619c535960e01b815260040160405180910390fd5b6000611c5685858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610dea92505050565b9050828161010001818151611c6b9190614704565b905250611c7781612e29565b95945050505050565b600054610100900460ff1615808015611ca05750600054600160ff909116105b80611cba5750303b158015611cba575060005460ff166001145b611cd65760405162461bcd60e51b8152600401610cba90614768565b6000805460ff191660011790558015611cf9576000805461ff0019166101001790555b80156110fd576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020016113a7565b600081815260026020526040812054808203611d6a57604051630e4f4df560e11b815260040160405180910390fd5b611d7560018261460b565b6001901b19841691505092915050565b7f000000000000000000000000000000000000000000000000000000000000000015611dc4576040516305b93ebf60e41b815260040160405180910390fd5b6110fd81336001613969565b600081815260026020526040812054808203611dff57604051630e4f4df560e11b815260040160405180910390fd5b6001611e0b818361460b565b81548110611e1b57611e1b61461e565b6000918252602090912001546001600160a01b03169392505050565b6060611e4233611b07565b611e5f5760405163619c535960e01b815260040160405180910390fd5b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611ea1925083915061279e9050565b611ead57611ead614634565b611eb7848461299f565b85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929998505050505050505050565b606082828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611f3c925083915061279e9050565b611f5c5760405163a85ba64f60e01b815260146004820152602401610cba565b6001600160a01b0387166000908152600460205260408120548891819003611f975760405163163cbe4360e01b815260040160405180910390fd5b618000811615611fb957604051628e12d960e21b815260040160405180910390fd5b87878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509250611ffa9150839050613a88565b90506001600160e01b031981166330d9c91560e01b148061202b57506001600160e01b0319811663d86ed3e560e01b145b8061204657506001600160e01b03198116630221347d60e61b145b8061206157506001600160e01b0319811663230dbd2960e01b145b8061207c57506001600160e01b03198116635f9e7d7760e01b145b8061209757506001600160e01b031981166353c11f9960e01b145b156120b5576040516377a14afb60e11b815260040160405180910390fd5b60006120f689898080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610dea92505050565b6101208101519091506001600160a01b03163314612127576040516311cfdef560e21b815260040160405180910390fd5b6060810180513390915261213a82612e29565b97506000806121818f8f8f8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f9250612f5d915050565b9150915081156121f4578080602001905181019061219f919061468f565b99506121aa8a61279e565b6121ca5760405163a85ba64f60e01b815260146004820152602401610cba565b6121d38a610dea565b6001600160a01b038416606082015293506121ed84612e29565b99506121fd565b6121fd81613016565b50505050505050505095945050505050565b60008181526002602052604081205480820361223e57604051630e4f4df560e11b815260040160405180910390fd5b61224960018261460b565b6001901b841791505092915050565b7f00000000000000000000000000000000000000000000000000000000000000001561235f5760006122c03284848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613ae492505050565b6000805460405163407b865d60e11b81529293504292620100009091046001600160a01b0316916380f70cba916122fd91309187906004016146e0565b602060405180830381865afa15801561231a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061233e91906145dc565b101561235d576040516319ab84d160e01b815260040160405180910390fd5b505b61236b83336001613969565b505050565b6000610dcb83838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061279e92505050565b600054610100900460ff16158080156123d15750600054600160ff909116105b806123eb5750303b1580156123eb575060005460ff166001145b6124075760405162461bcd60e51b8152600401610cba90614768565b6000805460ff19166001179055801561242a576000805461ff0019166101001790555b6000805462010000600160b01b031916620100006001600160a01b0385160217905580156115fe576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b60606000806001805490506001600160401b038111156124b7576124b7613ede565b6040519080825280602002602001820160405280156124e0578160200160208202803683370190505b50925060009050600091505b600154821015612577576001821b84161561256757600182815481106125145761251461461e565b6000918252602090912001546001600160a01b03168382612534816147b6565b9350815181106125465761254661461e565b60200260200101906001600160a01b031690816001600160a01b0316815250505b612570826147b6565b91506124ec565b825250919050565b6003546000906001600160a01b031661259a5761259a614634565b7f0000000000000000000000000000000000000000000000000000000000000000156125d057506003546001600160a01b031690565b600360009054906101000a90046001600160a01b03166001600160a01b03166350d75d256040518163ffffffff1660e01b8152600401602060405180830381865afa158015612623573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061112a919061474b565b333b600081900361266b5760405163353dacc360e21b815260040160405180910390fd5b507f00000000000000000000000000000000000000000000000000000000000000001561274357600061269d33613b17565b6000805460405163407b865d60e11b81529293509091620100009091046001600160a01b0316906380f70cba906126dc903090859087906004016146e0565b602060405180830381865afa1580156126f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061271d91906145dc565b6001149050806127405760405163289533c560e01b815260040160405180910390fd5b50505b6115fe81836000613969565b6001600160a01b03811660009081526004602090815260408083208151928301909152548082521580159291829161279657805161800081161515935064ff000000001691505b509193909250565b60008151600014158015610dce5750600654825160208401201492915050565b600060606001600160a01b0387166127d8576127d8614634565b6127e28484613b91565b935060005a9050861561286057876001600160a01b0316622dc6c06001600160401b03168660405161281491906147cf565b6000604051808303818686fa925050503d8060008114612850576040519150601f19603f3d011682016040523d82523d6000602084013e612855565b606091505b5090935091506128cf565b876001600160a01b0316622dc6c06001600160401b03168660405161288591906147cf565b60006040518083038160008787f1925050503d80600081146128c3576040519150601f19603f3d011682016040523d82523d6000602084013e6128c8565b606091505b5090935091505b82612940576128df603f826147eb565b5a111561290457856128f9576128f482613016565b612940565b6128f488600a61299f565b60405162461bcd60e51b815260206004820152601160248201527053463a206e656564206d6f72652067617360781b6044820152606401610cba565b509550959350505050565b600060408251101561295f57506000919050565b602082810151906000908214612979575060009392505050565b50604083015161298881613c48565b61299390604061480d565b84511492505050919050565b6001600160a01b0382166000908152600460205260408120546180001690036115fe576001600160a01b038216600081815260046020526040908190208054618000179055517fbe3aa33bd245135e4e26b223d79d14ea479a47bff09f2b03c53838af1edbb14b90611afb9084815260200190565b60065460609015612a3b5760405163a85ba64f60e01b815260156004820152602401610cba565b6001600160a01b0383166000908152600460205260408120548491819003612a765760405163163cbe4360e01b815260040160405180910390fd5b618000811615612a9857604051628e12d960e21b815260040160405180910390fd5b836000612aa482613a88565b90506001600160e01b031981166330d9c91560e01b1480612ad557506001600160e01b0319811663d86ed3e560e01b145b80612af057506001600160e01b03198116630221347d60e61b145b80612b0b57506001600160e01b0319811663230dbd2960e01b145b80612b2657506001600160e01b03198116635f9e7d7760e01b145b80612b4157506001600160e01b031981166353c11f9960e01b145b15612b5f576040516377a14afb60e11b815260040160405180910390fd5b60408051610160810182526000808252600260208084019190915242838501526001600160a01b03808d16606085015260808401839052845191820190945281815260a083015260c0820181905260e0820181905261010082018190529189166101208201526101408101829052612bd690612e29565b90506000612be5898984612f5d565b975090508015612c335786806020019051810190612c03919061468f565b9150612c0e8261279e565b612c2e5760405163a85ba64f60e01b815260146004820152602401610cba565b612c3c565b612c3c87613016565b5050600060065550929695505050505050565b60065460609015612c765760405163a85ba64f60e01b815260156004820152602401610cba565b83612c8081611b07565b612c9d5760405163619c535960e01b815260040160405180910390fd5b6000612ca885613a88565b6040805161016081018252600080825260016020830152929350612d2b9181014281526020018a6001600160a01b03168152602001846001600160e01b031916815260200187815260200160008152602001600081526020016000815260200160006001600160a01b0316815260200160006001600160a01b0316815250612e29565b90506000612d3a888884612f5d565b9550905080612d4c57612d4c85613016565b50506000600655509095945050505050565b612d66613cfb565b60608083806020019051810190612d7d9190614820565b81519193509150600090612d9a9084016020908101908501614879565b60a08901526001600160e01b03191660808801526001600160a01b031660608701526040860152602081811c600f168187015260ff9091168552825160009250612deb9190840181019084016148fd565b6001600160a01b03908116610140890152166101208701526101008601526001600160801b03811660c086015260801c60e085015250919392505050565b60606001826000015160ff161115612e575760405163a85ba64f60e01b815260286004820152602401610cba565b815160208084015160009260ff1664ff000000009190921b1617905060006080612e848560e00151613c81565b6001600160801b0316901b612e9c8560c00151613c81565b6001600160801b0316179050818460400151856060015186608001518760a00151604051602001612ed1959493929190614948565b60408051601f1981840301815282825261010087015161012088015161014089015160208601879052938501919091526001600160a01b03908116606085015290911660808301529060a00160408051601f1981840301815290829052612f3b9291602001614226565b60408051601f1981840301815291905280516020820120600655949350505050565b600060606001600160a01b038516612f7757612f77614634565b612f818484613b91565b9350846001600160a01b031684604051612f9b91906147cf565b6000604051808303816000865af19150503d8060008114612fd8576040519150601f19603f3d011682016040523d82523d6000602084013e612fdd565b606091505b509092509050811561300e57805160000361300e5760405163a85ba64f60e01b815260166004820152602401610cba565b935093915050565b6004815110156130685760405162461bcd60e51b815260206004820152601a60248201527f43616c6c5574696c733a207461726765742072657665727428290000000000006044820152606401610cba565b602081015163b1b7848f60e01b6001600160e01b03198216016131185760408051808201825260208082527f43616c6c5574696c733a207461726765742070616e69636b65643a2030785f5f90820190815260248501517f43616c6c5574696c733a207461726765742070616e69636b65643a2030780000600482811c600f908116603090810160081b918516011791909117909252925162461bcd60e51b8152919291610cba91849101613ecb565b81518060208401fd5b600061314b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6001600160a01b0316036131a15760405162461bcd60e51b815260206004820152601d60248201527f5555505350726f786961626c653a206e6f742075706772616461626c650000006044820152606401610cba565b806001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156131df573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061320391906145dc565b7fcd355cae2c435f8c5e0c626c4691d22fd85aa7422a424c6f0bced6e64c7aba741461327d5760405162461bcd60e51b815260206004820152602360248201527f5555505350726f786961626c653a206e6f7420636f6d70617469626c65206c6f60448201526267696360e81b6064820152608401610cba565b6001600160a01b03811630036132d55760405162461bcd60e51b815260206004820152601960248201527f5555505350726f786961626c653a2070726f7879206c6f6f70000000000000006044820152606401610cba565b6132fd817f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b7fe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc7fcd355cae2c435f8c5e0c626c4691d22fd85aa7422a424c6f0bced6e64c7aba74604080519182526001600160a01b0384166020830152016113a7565b6040805160208101829052603260608201527f6f72672e7375706572666c7569642d66696e616e63652e7375706572666c756960808201527132173a393ab9ba32b22337b93bb0b93232b960711b60a08201526001600160a01b0383169181019190915260009060c0015b604051602081830303815290604052805190602001209050919050565b6000601836108015906133fa57506133fa33611480565b61343e5760405162461bcd60e51b81526020600482015260156024820152742737ba103a393ab9ba32b2103337b93bb0b93232b960591b6044820152606401610cba565b5060131936013560601c90565b60005b8181101561396357600083838381811061346a5761346a61461e565b905060200281019061347c9190614994565b61348a9060208101906149aa565b905060001963ffffffff82160161357e576000808585858181106134b0576134b061461e565b90506020028101906134c29190614994565b6134d09060408101906149d0565b8101906134dd91906145b0565b915091508585858181106134f3576134f361461e565b90506020028101906135059190614994565b613516906040810190602001613d6b565b6001600160a01b03166362aa52878884846040518463ffffffff1660e01b8152600401613545939291906146e0565b600060405180830381600087803b15801561355f57600080fd5b505af1158015613573573d6000803e3d6000fd5b505050505050613952565b60011963ffffffff8216016136885760008060008686868181106135a4576135a461461e565b90506020028101906135b69190614994565b6135c49060408101906149d0565b8101906135d19190614a16565b9250925092508686868181106135e9576135e961461e565b90506020028101906135fb9190614994565b61360c906040810190602001613d6b565b604051630b682aeb60e11b81526001600160a01b038a81166004830152858116602483015284811660448301526064820184905291909116906316d055d690608401600060405180830381600087803b15801561366857600080fd5b505af115801561367c573d6000803e3d6000fd5b50505050505050613952565b60641963ffffffff82160161377d578383838181106136a9576136a961461e565b90506020028101906136bb9190614994565b6136cc906040810190602001613d6b565b6001600160a01b031663ca789464868686868181106136ed576136ed61461e565b90506020028101906136ff9190614994565b61370d9060408101906149d0565b81019061371a91906143a7565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b15801561376057600080fd5b505af1158015613774573d6000803e3d6000fd5b50505050613952565b60651963ffffffff8216016137e25783838381811061379e5761379e61461e565b90506020028101906137b09190614994565b6137c1906040810190602001613d6b565b6001600160a01b031663245887fc868686868181106136ed576136ed61461e565b60c81963ffffffff82160161387f576000808585858181106138065761380661461e565b90506020028101906138189190614994565b6138269060408101906149d0565b8101906138339190614a57565b915091506138778787878781811061384d5761384d61461e565b905060200281019061385f9190614994565b613870906040810190602001613d6b565b8484612c4f565b505050613952565b60c91963ffffffff82160161393957613933858585858181106138a4576138a461461e565b90506020028101906138b69190614994565b6138c7906040810190602001613d6b565b8686868181106138d9576138d961461e565b90506020028101906138eb9190614994565b6138f99060408101906149d0565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612a1492505050565b50613952565b60405163b477011560e01b815260040160405180910390fd5b5061395c816147b6565b905061344e565b50505050565b32330361398c5760405163a85ba64f60e01b815260026004820152602401610cba565b80156139b857813b80156139b65760405163a85ba64f60e01b815260016004820152602401610cba565b505b64ff000080ff1983161515806139cf575060ff8316155b806139dd5750618000831615155b156139fb57604051633d3200a960e21b815260040160405180910390fd5b6001600160a01b03821660009081526004602052604090205415613a32576040516301b0a93560e01b815260040160405180910390fd5b60408051602080820183528582526001600160a01b038516600081815260049092528382209251909255915190917f0d540ad8f39e07d19909687352b9fa017405d93c91a6760981fbae9cf28bfef791a2505050565b6000600482511015613adc5760405162461bcd60e51b815260206004820152601b60248201527f43616c6c5574696c733a20696e76616c69642063616c6c4461746100000000006044820152606401610cba565b506020015190565b60008282604051602001613af9929190614ab0565b60405160208183030381529060405280519060200120905092915050565b6040805160208101829052603960608201527f6f72672e7375706572666c7569642d66696e616e63652e7375706572666c756960808201527f642e61707057686974654c697374696e672e666163746f72790000000000000060a08201526001600160a01b0383169181019190915260009060c0016133c6565b815180830151606091908015613bba576040516367e9985b60e01b815260040160405180910390fd5b50601f1981018452825184908481613bd181613c48565b613bdb919061460b565b6001600160401b03811115613bf257613bf2613ede565b6040519080825280601f01601f191660200182016040528015613c1c576020820181803683370190505b50604051602001613c309493929190614b35565b60405160208183030381529060405291505092915050565b60008082601f1611613c5b576000613c5e565b60015b60ff16613c6c6020846147eb565b613c76919061480d565b610dce906020614b84565b60006001600160801b03821115613cea5760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20316044820152663238206269747360c81b6064820152608401610cba565b5090565b61024a80614ba483390190565b604080516101608101825260008082526020820181905291810182905260608082018390526080820183905260a082015260c0810182905260e081018290526101008101829052610120810182905261014081019190915290565b6001600160a01b03811681146110fd57600080fd5b600060208284031215613d7d57600080fd5b8135613d8881613d56565b9392505050565b60008083601f840112613da157600080fd5b5081356001600160401b03811115613db857600080fd5b602083019150836020828501011115613dd057600080fd5b9250929050565b80151581146110fd57600080fd5b60008060008060008060808789031215613dfe57600080fd5b8635613e0981613d56565b955060208701356001600160401b0380821115613e2557600080fd5b613e318a838b01613d8f565b909750955060408901359150613e4682613dd7565b90935060608801359080821115613e5c57600080fd5b50613e6989828a01613d8f565b979a9699509497509295939492505050565b60005b83811015613e96578181015183820152602001613e7e565b50506000910152565b60008151808452613eb7816020860160208601613e7b565b601f01601f19169290920160200192915050565b602081526000610dcb6020830184613e9f565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715613f1c57613f1c613ede565b604052919050565b60006001600160401b03821115613f3d57613f3d613ede565b50601f01601f191660200190565b600082601f830112613f5c57600080fd5b8135613f6f613f6a82613f24565b613ef4565b818152846020838601011115613f8457600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215613fb457600080fd5b8235613fbf81613d56565b915060208301356001600160401b03811115613fda57600080fd5b613fe685828601613f4b565b9150509250929050565b60008060006060848603121561400557600080fd5b833561401081613d56565b925060208401356001600160401b038082111561402c57600080fd5b61403887838801613f4b565b9350604086013591508082111561404e57600080fd5b5061405b86828701613f4b565b9150509250925092565b60006020828403121561407757600080fd5b81356001600160401b0381111561408d57600080fd5b610de284828501613f4b565b602081526140ad60208201835160ff169052565b600060208301516140c3604084018260ff169052565b506040830151606083015260608301516140e860808401826001600160a01b03169052565b5060808301516001600160e01b0319811660a08401525060a08301516101608060c085015261411b610180850183613e9f565b915060c085015160e085015260e0850151610100818187015280870151915050610120818187015280870151915050610140614161818701836001600160a01b03169052565b909501516001600160a01b031693019290925250919050565b60008060008060008060006080888a03121561419557600080fd5b87356141a081613d56565b965060208801356001600160401b03808211156141bc57600080fd5b6141c88b838c01613d8f565b909850965060408a01359150808211156141e157600080fd5b6141ed8b838c01613d8f565b909650945060608a013591508082111561420657600080fd5b506142138a828b01613d8f565b989b979a50959850939692959293505050565b6040815260006142396040830185613e9f565b8281036020840152611c778185613e9f565b60008060006040848603121561426057600080fd5b83356001600160401b0381111561427657600080fd5b61428286828701613d8f565b909790965060209590950135949350505050565b600080602083850312156142a957600080fd5b82356001600160401b03808211156142c057600080fd5b818501915085601f8301126142d457600080fd5b8135818111156142e357600080fd5b8660208260051b85010111156142f857600080fd5b60209290920196919550909350505050565b60008060008060008060a0878903121561432357600080fd5b86356001600160401b0381111561433957600080fd5b61434589828a01613d8f565b909750955050602087013561435981613d56565b93506040870135925060608701359150608087013561437781613d56565b809150509295509295509295565b6000806040838503121561439857600080fd5b50508035926020909101359150565b6000602082840312156143b957600080fd5b5035919050565b600080600080606085870312156143d657600080fd5b84356001600160401b038111156143ec57600080fd5b6143f887828801613d8f565b909550935050602085013561440c81613d56565b9396929550929360400135925050565b60008060008060006060868803121561443457600080fd5b853561443f81613d56565b945060208601356001600160401b038082111561445b57600080fd5b61446789838a01613d8f565b9096509450604088013591508082111561448057600080fd5b5061448d88828901613d8f565b969995985093965092949392505050565b600080604083850312156144b157600080fd5b82356144bc81613d56565b915060208301356144cc81613d56565b809150509250929050565b6000806000604084860312156144ec57600080fd5b8335925060208401356001600160401b0381111561450957600080fd5b61451586828701613d8f565b9497909650939450505050565b6000806020838503121561453557600080fd5b82356001600160401b0381111561454b57600080fd5b61455785828601613d8f565b90969095509350505050565b6020808252825182820181905260009190848201906040850190845b818110156145a45783516001600160a01b03168352928401929184019160010161457f565b50909695505050505050565b600080604083850312156145c357600080fd5b82356145ce81613d56565b946020939093013593505050565b6000602082840312156145ee57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b81810381811115610dce57610dce6145f5565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052600160045260246000fd5b600082601f83011261465b57600080fd5b8151614669613f6a82613f24565b81815284602083860101111561467e57600080fd5b610de2826020830160208701613e7b565b6000602082840312156146a157600080fd5b81516001600160401b038111156146b757600080fd5b610de28482850161464a565b6000602082840312156146d557600080fd5b8151613d8881613dd7565b6001600160a01b039384168152919092166020820152604081019190915260600190565b8082018281126000831280158216821582161715614724576147246145f5565b505092915050565b600060ff821660ff8103614742576147426145f5565b60010192915050565b60006020828403121561475d57600080fd5b8151613d8881613d56565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b6000600182016147c8576147c86145f5565b5060010190565b600082516147e1818460208701613e7b565b9190910192915050565b60008261480857634e487b7160e01b600052601260045260246000fd5b500490565b80820180821115610dce57610dce6145f5565b6000806040838503121561483357600080fd5b82516001600160401b038082111561484a57600080fd5b6148568683870161464a565b9350602085015191508082111561486c57600080fd5b50613fe68582860161464a565b600080600080600060a0868803121561489157600080fd5b855194506020860151935060408601516148aa81613d56565b60608701519093506001600160e01b0319811681146148c857600080fd5b60808701519092506001600160401b038111156148e457600080fd5b6148f08882890161464a565b9150509295509295909350565b6000806000806080858703121561491357600080fd5b8451935060208501519250604085015161492c81613d56565b606086015190925061493d81613d56565b939692955090935050565b858152602081018590526001600160a01b03841660408201526001600160e01b03198316606082015260a06080820181905260009061498990830184613e9f565b979650505050505050565b60008235605e198336030181126147e157600080fd5b6000602082840312156149bc57600080fd5b813563ffffffff81168114613d8857600080fd5b6000808335601e198436030181126149e757600080fd5b8301803591506001600160401b03821115614a0157600080fd5b602001915036819003821315613dd057600080fd5b600080600060608486031215614a2b57600080fd5b8335614a3681613d56565b92506020840135614a4681613d56565b929592945050506040919091013590565b60008060408385031215614a6a57600080fd5b82356001600160401b0380821115614a8157600080fd5b614a8d86838701613f4b565b93506020850135915080821115614aa357600080fd5b50613fe685828601613f4b565b60608152604160608201527f6f72672e7375706572666c7569642d66696e616e63652e7375706572666c756960808201527f642e61707057686974654c697374696e672e726567697374726174696f6e4b6560a0820152607960f81b60c082015260018060a01b038316602082015260e060408201526000610de260e0830184613e9f565b600085516020614b488285838b01613e7b565b81840191508682528551614b6181838501848a01613e7b565b8551920191614b7581838501848901613e7b565b91909101019695505050505050565b6000816000190483118215151615614b9e57614b9e6145f5565b50029056fe608060405234801561001057600080fd5b5061022a806100206000396000f3fe6080604052600436106100225760003560e01c80634a0687ef1461003957610031565b366100315761002f610059565b005b61002f610059565b34801561004557600080fd5b5061002f6100543660046101c4565b61006b565b610069610064610171565b6101a0565b565b6001600160a01b0381166100c65760405162461bcd60e51b815260206004820152601760248201527f5555505350726f78793a207a65726f206164647265737300000000000000000060448201526064015b60405180910390fd5b60006100f07f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6001600160a01b0316146101465760405162461bcd60e51b815260206004820152601e60248201527f5555505350726f78793a20616c726561647920696e697469616c697a6564000060448201526064016100bd565b61016e817f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b50565b600061019b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905090565b3660008037600080366000845af43d6000803e8080156101bf573d6000f35b3d6000fd5b6000602082840312156101d657600080fd5b81356001600160a01b03811681146101ed57600080fd5b939250505056fea2646970667358221220d5a8e007f2080dfe84e95d171924fb4d89e3b402dfeaf170fb33ddf8acb5db0e64736f6c63430008100033a2646970667358221220af187faf3e5f1ddf4fbc57a06821f859abe766745f72d1c8988633d43c44f47064736f6c6343000810003300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
Deployed ByteCode
0x608060405234801561001057600080fd5b50600436106102a05760003560e01c8063768fabb011610167578063bb84cfa1116100ce578063c56a069d11610087578063c56a069d14610697578063cd312ec4146106b7578063e8dccb7d146106de578063f2e55caf14610700578063f373305214610708578063f9f522f41461071b57600080fd5b8063bb84cfa114610609578063bbe4fd5014610645578063bced3ddc1461064b578063bd1c448b1461065e578063bf42873414610671578063c4d66de81461068457600080fd5b80639d297e30116101205780639d297e3014610583578063a5dbbbcd146105aa578063ad3915c8146105bd578063b6d200de146105d0578063b724211e146105e3578063ba48b5f8146105f657600080fd5b8063768fabb01461050a578063787afde71461051d5780638ca48484146105305780639378fa1314610543578063989b0c3e146105685780639903ad381461057b57600080fd5b806350d75d251161020b578063670e77e3116101c4578063670e77e31461049a5780636ad3ca7d146104ad5780636b4f3335146104c05780637283100c146104d3578063731aed6e146104e657806374041e02146104f757600080fd5b806350d75d251461041657806352d1902d1461041e57806354fbc4931461044e57806357121e0c14610461578063572b6c051461047457806359a291411461048757600080fd5b806339255d5b1161025d57806339255d5b146103565780633ca3ad4e146103695780633f6c923a146103a45780634329d293146103c457806346951954146103e5578063486ff0cd146103f857600080fd5b806306cecba8146102a557806315a024e1146102ba5780631e6d0a84146102cd5780631e855cf3146102f6578063289b3c0d1461030957806333d608f114610334575b600080fd5b6102b86102b3366004613d6b565b61074b565b005b6102b86102c8366004613d6b565b610922565b6102e06102db366004613de5565b610b72565b6040516102ed9190613ecb565b60405180910390f35b6102e0610304366004613fa1565b610dbe565b6000546201000090046001600160a01b03165b6040516001600160a01b0390911681526020016102ed565b61033e622dc6c081565b6040516001600160401b0390911681526020016102ed565b6102e0610364366004613ff0565b610dd4565b610394610377366004613d6b565b6001600160a01b0316600090815260046020526040902054151590565b60405190151581526020016102ed565b6103b76103b2366004614065565b610dea565b6040516102ed9190614099565b6103d76103d236600461417a565b610dfb565b6040516102ed929190614226565b6102b86103f3366004613d6b565b611004565b604080518082019091526002815261763160f01b60208201526102e0565b61031c611100565b7fcd355cae2c435f8c5e0c626c4691d22fd85aa7422a424c6f0bced6e64c7aba745b6040519081526020016102ed565b6102b861045c366004613d6b565b61112f565b6102b861046f366004613d6b565b6113b2565b610394610482366004613d6b565b611480565b6102e061049536600461424b565b61150a565b6102b86104a8366004614296565b6115ec565b6102b86104bb366004614296565b611602565b6103946104ce366004613d6b565b61160d565b6102b86104e1366004613d6b565b611631565b6003546001600160a01b031661031c565b6102e0610505366004613de5565b6116d9565b6102e061051836600461430a565b611828565b6102b861052b366004613d6b565b6119c4565b61039461053e366004613d6b565b611b07565b610556610551366004613d6b565b611bcc565b60405160ff90911681526020016102ed565b6102e061057636600461424b565b611bed565b6102b8611c80565b6103947f000000000000000000000000000000000000000000000000000000000000000181565b6104406105b8366004614385565b611d3b565b6102b86105cb3660046143a7565b611d85565b61031c6105de3660046143a7565b611dd0565b6102e06105f13660046143c0565b611e37565b6102e061060436600461441c565b611ef8565b61039461061736600461449e565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b42610440565b610440610659366004614385565b61220f565b6102b861066c3660046144d7565b612258565b61039461067f366004614522565b612370565b6102b8610692366004613d6b565b6123b1565b6106aa6106a53660046143a7565b612495565b6040516102ed9190614563565b6103947f000000000000000000000000000000000000000000000000000000000000000081565b6103946106ec3660046143a7565b600090815260026020526040902054151590565b61031c61257f565b6102b86107163660046145b0565b612647565b61072e610729366004613d6b565b61274f565b6040805193151584529115156020840152908201526060016102ed565b6000546201000090046001600160a01b0316331461077c576040516362e9152760e11b815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000000000000156107bb576040516314f72c9f60e01b815260040160405180910390fd5b6000816001600160a01b0316637730599e6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107fb573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061081f91906145dc565b60008181526002602052604081205491925081900361085157604051630e4f4df560e11b815260040160405180910390fd5b6000600161085f818461460b565b8154811061086f5761086f61461e565b6000918252602090912001546040516311a5465560e21b81526001600160a01b03868116600483015290911691508190634695195490602401600060405180830381600087803b1580156108c257600080fd5b505af11580156108d6573d6000803e3d6000fd5b5050604080518681526001600160a01b03881660208201527f9279aa773f2b588996032d8de89911555039f28b13a11a7c17074330bc082d9a935001905060405180910390a150505050565b6000546201000090046001600160a01b03163314610953576040516362e9152760e11b815260040160405180910390fd5b6000816001600160a01b0316637730599e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610993573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109b791906145dc565b600081815260026020526040902054909150156109e757604051631b93bb7560e31b815260040160405180910390fd5b60015461010011610a0b57604051630f85034f60e31b815260040160405180910390fd5b60007f0000000000000000000000000000000000000000000000000000000000000000610ac5576000604051610a4090613cee565b604051809103906000f080158015610a5c573d6000803e3d6000fd5b50604051634a0687ef60e01b81526001600160a01b03868116600483015291925090821690634a0687ef90602401600060405180830381600087803b158015610aa457600080fd5b505af1158015610ab8573d6000803e3d6000fd5b5050505080915050610ac8565b50815b6001805480820182557fb10e2d527612073b26eecdfd717e6a320cf44b4afac2b0732d9fcbe2b7fa0cf60180546001600160a01b0384166001600160a01b0319909116179055546000838152600260205260409081902091909155517f878135063a6cfb3bc333e534b1fdc83f4f12221cad6705c31c0567048a8bd3d190610b6590849086909182526001600160a01b0316602082015260400190565b60405180910390a1505050565b6060610b7d33611b07565b610b9a5760405163619c535960e01b815260040160405180910390fd5b82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610bdc925083915061279e9050565b610be857610be8614634565b600080610c628a6000898c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8f018190048102820181019092528d815292508d91508c90819084018382808284376000920191909152506127be92505050565b915091508115610d7757610c758161294b565b15610d0f5780806020019051810190610c8e919061468f565b9350610c998461279e565b610d0a5786610cc35760405163a85ba64f60e01b8152601460048201526024015b60405180910390fd5b85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929650610d0a92508c91506014905061299f565b610db1565b86610d305760405163a85ba64f60e01b815260166004820152602401610cba565b85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929650610d0a92508c91506016905061299f565b85858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509296505050505b5050509695505050505050565b6060610dcb338484612a14565b90505b92915050565b6060610de233858585612c4f565b949350505050565b610df2613cfb565b610dce82612d5e565b60608083838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610e40925083915061279e9050565b610e605760405163a85ba64f60e01b815260146004820152602401610cba565b89610e6a81611b07565b610e875760405163619c535960e01b815260040160405180910390fd5b6000610ec887878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610dea92505050565b6101208101519091506001600160a01b03163314610ef95760405163066875e160e11b815260040160405180910390fd5b60608101805133909152604080516020601f8c018190048102820181019092528a8152908b908b908190840183828082843760009201919091525050505060a0830152610f4582612e29565b95506000610f8b8e8e8e8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508c9250612f5d915050565b965090508015610fea5785806020019051810190610fa9919061468f565b9650610fb48761279e565b610fc057610fc0614634565b610fc987610dea565b6001600160a01b03831660608201529250610fe383612e29565b9650610ff3565b610ff386613016565b505050505097509795505050505050565b6000546201000090046001600160a01b03163314611035576040516362e9152760e11b815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000015611074576040516314f72c9f60e01b815260040160405180910390fd5b806001600160a01b031663cd312ec46040518163ffffffff1660e01b8152600401602060405180830381865afa1580156110b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110d691906146c3565b156110f45760405163474e764160e01b815260040160405180910390fd5b6110fd81613121565b50565b600061112a7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905090565b6000546201000090046001600160a01b03163314611160576040516362e9152760e11b815260040160405180910390fd5b6003546001600160a01b03166112cf577f00000000000000000000000000000000000000000000000000000000000000006112465760006040516111a390613cee565b604051809103906000f0801580156111bf573d6000803e3d6000fd5b50604051634a0687ef60e01b81526001600160a01b03848116600483015291925090821690634a0687ef90602401600060405180830381600087803b15801561120757600080fd5b505af115801561121b573d6000803e3d6000fd5b5050600380546001600160a01b0319166001600160a01b039490941693909317909255506112629050565b600380546001600160a01b0319166001600160a01b0383161790555b600360009054906101000a90046001600160a01b03166001600160a01b0316638129fc1c6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156112b257600080fd5b505af11580156112c6573d6000803e3d6000fd5b5050505061136e565b7f00000000000000000000000000000000000000000000000000000000000000001561130e576040516314f72c9f60e01b815260040160405180910390fd5b6003546040516311a5465560e21b81526001600160a01b03838116600483015290911690634695195490602401600060405180830381600087803b15801561135557600080fd5b505af1158015611369573d6000803e3d6000fd5b505050505b6003546040516001600160a01b0390911681527fce13a9895a1719ad4493b2ac1a9bfb36070566161abab408e7ecbe586da8d499906020015b60405180910390a150565b336000818152600460205260409020546113df576040516302eb3f7160e61b815260040160405180910390fd5b6001600160a01b03821660009081526004602052604090205461141557604051634b5518af60e11b815260040160405180910390fd5b61141e82611bcc565b60ff1661142a82611bcc565b60ff161161144b57604051630447252760e41b815260040160405180910390fd5b6001600160a01b039081166000908152600560209081526040808320949093168252929092529020805460ff19166001179055565b600080546201000090046001600160a01b03166380f70cba30836114a38661335b565b6040518463ffffffff1660e01b81526004016114c1939291906146e0565b602060405180830381865afa1580156114de573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061150291906145dc565b151592915050565b606061151533611b07565b6115325760405163619c535960e01b815260040160405180910390fd5b83838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611574925083915061279e9050565b61158057611580614634565b60006115c186868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610dea92505050565b90508381610100018181516115d69190614704565b9052506115e281612e29565b9695505050505050565b6115fe6115f76133e3565b838361344b565b5050565b6115fe33838361344b565b6001600160a01b038116600090815260046020526040812054618000161515610dce565b6000546201000090046001600160a01b03163314611662576040516362e9152760e11b815260040160405180910390fd5b600054604080516001600160a01b03620100009093048316815291831660208301527f13abda02e63c790d0e2818b251282cfe5cbe0a8abd69c54bf5d2260c0907bd2e910160405180910390a1600080546001600160a01b03909216620100000262010000600160b01b0319909216919091179055565b60606116e433611b07565b6117015760405163619c535960e01b815260040160405180910390fd5b82828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611743925083915061279e9050565b61174f5761174f614634565b6000806117c98a6001898c8c8080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8f018190048102820181019092528d815292508d91508c90819084018382808284376000920191909152506127be92505050565b915091508115610db1576117dc8161294b565b156117fc57808060200190518101906117f5919061468f565b9350610db1565b8661181d5760405163a85ba64f60e01b815260166004820152602401610cba565b610db18a601661299f565b606061183333611b07565b6118505760405163619c535960e01b815260040160405180910390fd5b86868080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611892925083915061279e9050565b61189e5761189e614634565b60006118df89898080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610dea92505050565b905061190681606001516001600160a01b0316600090815260046020526040902054151590565b801561191a57506001816000015160ff1610155b1561196d5760608101516001600160a01b039081166000908152600560209081526040808320938b168352929052205460ff1661196d5760405163a85ba64f60e01b8152601e6004820152602401610cba565b8051816119798261472c565b60ff169052506003602082015260c0810186905261010081018590526001600160a01b0380881661012083015284166101408201526119b781612e29565b9998505050505050505050565b6000546201000090046001600160a01b031633146119f5576040516362e9152760e11b815260040160405180910390fd5b60035460408051634a3852d960e11b815290516000926001600160a01b031691639470a5b29160048083019260209291908290030181865afa158015611a3f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a63919061474b565b6040516311a5465560e21b81526001600160a01b03808316600483015291925090831690634695195490602401600060405180830381600087803b158015611aaa57600080fd5b505af1158015611abe573d6000803e3d6000fd5b50506040516001600160a01b038481168252851692507f840acbd291b38534819f47f875839277e502f40e1c7bfea2c5fc2c8017442cd391506020015b60405180910390a25050565b600080826001600160a01b0316637730599e6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611b48573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b6c91906145dc565b6000818152600260205260409020549091508015801590610de257506001600160a01b0384166001611b9e818461460b565b81548110611bae57611bae61461e565b6000918252602090912001546001600160a01b031614949350505050565b6001600160a01b03811660009081526004602052604081205460ff16610dce565b6060611bf833611b07565b611c155760405163619c535960e01b815260040160405180910390fd5b6000611c5685858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610dea92505050565b9050828161010001818151611c6b9190614704565b905250611c7781612e29565b95945050505050565b600054610100900460ff1615808015611ca05750600054600160ff909116105b80611cba5750303b158015611cba575060005460ff166001145b611cd65760405162461bcd60e51b8152600401610cba90614768565b6000805460ff191660011790558015611cf9576000805461ff0019166101001790555b80156110fd576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498906020016113a7565b600081815260026020526040812054808203611d6a57604051630e4f4df560e11b815260040160405180910390fd5b611d7560018261460b565b6001901b19841691505092915050565b7f000000000000000000000000000000000000000000000000000000000000000115611dc4576040516305b93ebf60e41b815260040160405180910390fd5b6110fd81336001613969565b600081815260026020526040812054808203611dff57604051630e4f4df560e11b815260040160405180910390fd5b6001611e0b818361460b565b81548110611e1b57611e1b61461e565b6000918252602090912001546001600160a01b03169392505050565b6060611e4233611b07565b611e5f5760405163619c535960e01b815260040160405180910390fd5b84848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611ea1925083915061279e9050565b611ead57611ead614634565b611eb7848461299f565b85858080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250929998505050505050505050565b606082828080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611f3c925083915061279e9050565b611f5c5760405163a85ba64f60e01b815260146004820152602401610cba565b6001600160a01b0387166000908152600460205260408120548891819003611f975760405163163cbe4360e01b815260040160405180910390fd5b618000811615611fb957604051628e12d960e21b815260040160405180910390fd5b87878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509250611ffa9150839050613a88565b90506001600160e01b031981166330d9c91560e01b148061202b57506001600160e01b0319811663d86ed3e560e01b145b8061204657506001600160e01b03198116630221347d60e61b145b8061206157506001600160e01b0319811663230dbd2960e01b145b8061207c57506001600160e01b03198116635f9e7d7760e01b145b8061209757506001600160e01b031981166353c11f9960e01b145b156120b5576040516377a14afb60e11b815260040160405180910390fd5b60006120f689898080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250610dea92505050565b6101208101519091506001600160a01b03163314612127576040516311cfdef560e21b815260040160405180910390fd5b6060810180513390915261213a82612e29565b97506000806121818f8f8f8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508f9250612f5d915050565b9150915081156121f4578080602001905181019061219f919061468f565b99506121aa8a61279e565b6121ca5760405163a85ba64f60e01b815260146004820152602401610cba565b6121d38a610dea565b6001600160a01b038416606082015293506121ed84612e29565b99506121fd565b6121fd81613016565b50505050505050505095945050505050565b60008181526002602052604081205480820361223e57604051630e4f4df560e11b815260040160405180910390fd5b61224960018261460b565b6001901b841791505092915050565b7f00000000000000000000000000000000000000000000000000000000000000011561235f5760006122c03284848080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250613ae492505050565b6000805460405163407b865d60e11b81529293504292620100009091046001600160a01b0316916380f70cba916122fd91309187906004016146e0565b602060405180830381865afa15801561231a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061233e91906145dc565b101561235d576040516319ab84d160e01b815260040160405180910390fd5b505b61236b83336001613969565b505050565b6000610dcb83838080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061279e92505050565b600054610100900460ff16158080156123d15750600054600160ff909116105b806123eb5750303b1580156123eb575060005460ff166001145b6124075760405162461bcd60e51b8152600401610cba90614768565b6000805460ff19166001179055801561242a576000805461ff0019166101001790555b6000805462010000600160b01b031916620100006001600160a01b0385160217905580156115fe576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15050565b60606000806001805490506001600160401b038111156124b7576124b7613ede565b6040519080825280602002602001820160405280156124e0578160200160208202803683370190505b50925060009050600091505b600154821015612577576001821b84161561256757600182815481106125145761251461461e565b6000918252602090912001546001600160a01b03168382612534816147b6565b9350815181106125465761254661461e565b60200260200101906001600160a01b031690816001600160a01b0316815250505b612570826147b6565b91506124ec565b825250919050565b6003546000906001600160a01b031661259a5761259a614634565b7f0000000000000000000000000000000000000000000000000000000000000000156125d057506003546001600160a01b031690565b600360009054906101000a90046001600160a01b03166001600160a01b03166350d75d256040518163ffffffff1660e01b8152600401602060405180830381865afa158015612623573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061112a919061474b565b333b600081900361266b5760405163353dacc360e21b815260040160405180910390fd5b507f00000000000000000000000000000000000000000000000000000000000000011561274357600061269d33613b17565b6000805460405163407b865d60e11b81529293509091620100009091046001600160a01b0316906380f70cba906126dc903090859087906004016146e0565b602060405180830381865afa1580156126f9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061271d91906145dc565b6001149050806127405760405163289533c560e01b815260040160405180910390fd5b50505b6115fe81836000613969565b6001600160a01b03811660009081526004602090815260408083208151928301909152548082521580159291829161279657805161800081161515935064ff000000001691505b509193909250565b60008151600014158015610dce5750600654825160208401201492915050565b600060606001600160a01b0387166127d8576127d8614634565b6127e28484613b91565b935060005a9050861561286057876001600160a01b0316622dc6c06001600160401b03168660405161281491906147cf565b6000604051808303818686fa925050503d8060008114612850576040519150601f19603f3d011682016040523d82523d6000602084013e612855565b606091505b5090935091506128cf565b876001600160a01b0316622dc6c06001600160401b03168660405161288591906147cf565b60006040518083038160008787f1925050503d80600081146128c3576040519150601f19603f3d011682016040523d82523d6000602084013e6128c8565b606091505b5090935091505b82612940576128df603f826147eb565b5a111561290457856128f9576128f482613016565b612940565b6128f488600a61299f565b60405162461bcd60e51b815260206004820152601160248201527053463a206e656564206d6f72652067617360781b6044820152606401610cba565b509550959350505050565b600060408251101561295f57506000919050565b602082810151906000908214612979575060009392505050565b50604083015161298881613c48565b61299390604061480d565b84511492505050919050565b6001600160a01b0382166000908152600460205260408120546180001690036115fe576001600160a01b038216600081815260046020526040908190208054618000179055517fbe3aa33bd245135e4e26b223d79d14ea479a47bff09f2b03c53838af1edbb14b90611afb9084815260200190565b60065460609015612a3b5760405163a85ba64f60e01b815260156004820152602401610cba565b6001600160a01b0383166000908152600460205260408120548491819003612a765760405163163cbe4360e01b815260040160405180910390fd5b618000811615612a9857604051628e12d960e21b815260040160405180910390fd5b836000612aa482613a88565b90506001600160e01b031981166330d9c91560e01b1480612ad557506001600160e01b0319811663d86ed3e560e01b145b80612af057506001600160e01b03198116630221347d60e61b145b80612b0b57506001600160e01b0319811663230dbd2960e01b145b80612b2657506001600160e01b03198116635f9e7d7760e01b145b80612b4157506001600160e01b031981166353c11f9960e01b145b15612b5f576040516377a14afb60e11b815260040160405180910390fd5b60408051610160810182526000808252600260208084019190915242838501526001600160a01b03808d16606085015260808401839052845191820190945281815260a083015260c0820181905260e0820181905261010082018190529189166101208201526101408101829052612bd690612e29565b90506000612be5898984612f5d565b975090508015612c335786806020019051810190612c03919061468f565b9150612c0e8261279e565b612c2e5760405163a85ba64f60e01b815260146004820152602401610cba565b612c3c565b612c3c87613016565b5050600060065550929695505050505050565b60065460609015612c765760405163a85ba64f60e01b815260156004820152602401610cba565b83612c8081611b07565b612c9d5760405163619c535960e01b815260040160405180910390fd5b6000612ca885613a88565b6040805161016081018252600080825260016020830152929350612d2b9181014281526020018a6001600160a01b03168152602001846001600160e01b031916815260200187815260200160008152602001600081526020016000815260200160006001600160a01b0316815260200160006001600160a01b0316815250612e29565b90506000612d3a888884612f5d565b9550905080612d4c57612d4c85613016565b50506000600655509095945050505050565b612d66613cfb565b60608083806020019051810190612d7d9190614820565b81519193509150600090612d9a9084016020908101908501614879565b60a08901526001600160e01b03191660808801526001600160a01b031660608701526040860152602081811c600f168187015260ff9091168552825160009250612deb9190840181019084016148fd565b6001600160a01b03908116610140890152166101208701526101008601526001600160801b03811660c086015260801c60e085015250919392505050565b60606001826000015160ff161115612e575760405163a85ba64f60e01b815260286004820152602401610cba565b815160208084015160009260ff1664ff000000009190921b1617905060006080612e848560e00151613c81565b6001600160801b0316901b612e9c8560c00151613c81565b6001600160801b0316179050818460400151856060015186608001518760a00151604051602001612ed1959493929190614948565b60408051601f1981840301815282825261010087015161012088015161014089015160208601879052938501919091526001600160a01b03908116606085015290911660808301529060a00160408051601f1981840301815290829052612f3b9291602001614226565b60408051601f1981840301815291905280516020820120600655949350505050565b600060606001600160a01b038516612f7757612f77614634565b612f818484613b91565b9350846001600160a01b031684604051612f9b91906147cf565b6000604051808303816000865af19150503d8060008114612fd8576040519150601f19603f3d011682016040523d82523d6000602084013e612fdd565b606091505b509092509050811561300e57805160000361300e5760405163a85ba64f60e01b815260166004820152602401610cba565b935093915050565b6004815110156130685760405162461bcd60e51b815260206004820152601a60248201527f43616c6c5574696c733a207461726765742072657665727428290000000000006044820152606401610cba565b602081015163b1b7848f60e01b6001600160e01b03198216016131185760408051808201825260208082527f43616c6c5574696c733a207461726765742070616e69636b65643a2030785f5f90820190815260248501517f43616c6c5574696c733a207461726765742070616e69636b65643a2030780000600482811c600f908116603090810160081b918516011791909117909252925162461bcd60e51b8152919291610cba91849101613ecb565b81518060208401fd5b600061314b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6001600160a01b0316036131a15760405162461bcd60e51b815260206004820152601d60248201527f5555505350726f786961626c653a206e6f742075706772616461626c650000006044820152606401610cba565b806001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156131df573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061320391906145dc565b7fcd355cae2c435f8c5e0c626c4691d22fd85aa7422a424c6f0bced6e64c7aba741461327d5760405162461bcd60e51b815260206004820152602360248201527f5555505350726f786961626c653a206e6f7420636f6d70617469626c65206c6f60448201526267696360e81b6064820152608401610cba565b6001600160a01b03811630036132d55760405162461bcd60e51b815260206004820152601960248201527f5555505350726f786961626c653a2070726f7879206c6f6f70000000000000006044820152606401610cba565b6132fd817f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b7fe011bc04c286c344a8fcbb8de77f953da762c3e25d8cdea984147fc4168a5dcc7fcd355cae2c435f8c5e0c626c4691d22fd85aa7422a424c6f0bced6e64c7aba74604080519182526001600160a01b0384166020830152016113a7565b6040805160208101829052603260608201527f6f72672e7375706572666c7569642d66696e616e63652e7375706572666c756960808201527132173a393ab9ba32b22337b93bb0b93232b960711b60a08201526001600160a01b0383169181019190915260009060c0015b604051602081830303815290604052805190602001209050919050565b6000601836108015906133fa57506133fa33611480565b61343e5760405162461bcd60e51b81526020600482015260156024820152742737ba103a393ab9ba32b2103337b93bb0b93232b960591b6044820152606401610cba565b5060131936013560601c90565b60005b8181101561396357600083838381811061346a5761346a61461e565b905060200281019061347c9190614994565b61348a9060208101906149aa565b905060001963ffffffff82160161357e576000808585858181106134b0576134b061461e565b90506020028101906134c29190614994565b6134d09060408101906149d0565b8101906134dd91906145b0565b915091508585858181106134f3576134f361461e565b90506020028101906135059190614994565b613516906040810190602001613d6b565b6001600160a01b03166362aa52878884846040518463ffffffff1660e01b8152600401613545939291906146e0565b600060405180830381600087803b15801561355f57600080fd5b505af1158015613573573d6000803e3d6000fd5b505050505050613952565b60011963ffffffff8216016136885760008060008686868181106135a4576135a461461e565b90506020028101906135b69190614994565b6135c49060408101906149d0565b8101906135d19190614a16565b9250925092508686868181106135e9576135e961461e565b90506020028101906135fb9190614994565b61360c906040810190602001613d6b565b604051630b682aeb60e11b81526001600160a01b038a81166004830152858116602483015284811660448301526064820184905291909116906316d055d690608401600060405180830381600087803b15801561366857600080fd5b505af115801561367c573d6000803e3d6000fd5b50505050505050613952565b60641963ffffffff82160161377d578383838181106136a9576136a961461e565b90506020028101906136bb9190614994565b6136cc906040810190602001613d6b565b6001600160a01b031663ca789464868686868181106136ed576136ed61461e565b90506020028101906136ff9190614994565b61370d9060408101906149d0565b81019061371a91906143a7565b6040516001600160e01b031960e085901b1681526001600160a01b0390921660048301526024820152604401600060405180830381600087803b15801561376057600080fd5b505af1158015613774573d6000803e3d6000fd5b50505050613952565b60651963ffffffff8216016137e25783838381811061379e5761379e61461e565b90506020028101906137b09190614994565b6137c1906040810190602001613d6b565b6001600160a01b031663245887fc868686868181106136ed576136ed61461e565b60c81963ffffffff82160161387f576000808585858181106138065761380661461e565b90506020028101906138189190614994565b6138269060408101906149d0565b8101906138339190614a57565b915091506138778787878781811061384d5761384d61461e565b905060200281019061385f9190614994565b613870906040810190602001613d6b565b8484612c4f565b505050613952565b60c91963ffffffff82160161393957613933858585858181106138a4576138a461461e565b90506020028101906138b69190614994565b6138c7906040810190602001613d6b565b8686868181106138d9576138d961461e565b90506020028101906138eb9190614994565b6138f99060408101906149d0565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612a1492505050565b50613952565b60405163b477011560e01b815260040160405180910390fd5b5061395c816147b6565b905061344e565b50505050565b32330361398c5760405163a85ba64f60e01b815260026004820152602401610cba565b80156139b857813b80156139b65760405163a85ba64f60e01b815260016004820152602401610cba565b505b64ff000080ff1983161515806139cf575060ff8316155b806139dd5750618000831615155b156139fb57604051633d3200a960e21b815260040160405180910390fd5b6001600160a01b03821660009081526004602052604090205415613a32576040516301b0a93560e01b815260040160405180910390fd5b60408051602080820183528582526001600160a01b038516600081815260049092528382209251909255915190917f0d540ad8f39e07d19909687352b9fa017405d93c91a6760981fbae9cf28bfef791a2505050565b6000600482511015613adc5760405162461bcd60e51b815260206004820152601b60248201527f43616c6c5574696c733a20696e76616c69642063616c6c4461746100000000006044820152606401610cba565b506020015190565b60008282604051602001613af9929190614ab0565b60405160208183030381529060405280519060200120905092915050565b6040805160208101829052603960608201527f6f72672e7375706572666c7569642d66696e616e63652e7375706572666c756960808201527f642e61707057686974654c697374696e672e666163746f72790000000000000060a08201526001600160a01b0383169181019190915260009060c0016133c6565b815180830151606091908015613bba576040516367e9985b60e01b815260040160405180910390fd5b50601f1981018452825184908481613bd181613c48565b613bdb919061460b565b6001600160401b03811115613bf257613bf2613ede565b6040519080825280601f01601f191660200182016040528015613c1c576020820181803683370190505b50604051602001613c309493929190614b35565b60405160208183030381529060405291505092915050565b60008082601f1611613c5b576000613c5e565b60015b60ff16613c6c6020846147eb565b613c76919061480d565b610dce906020614b84565b60006001600160801b03821115613cea5760405162461bcd60e51b815260206004820152602760248201527f53616665436173743a2076616c756520646f65736e27742066697420696e20316044820152663238206269747360c81b6064820152608401610cba565b5090565b61024a80614ba483390190565b604080516101608101825260008082526020820181905291810182905260608082018390526080820183905260a082015260c0810182905260e081018290526101008101829052610120810182905261014081019190915290565b6001600160a01b03811681146110fd57600080fd5b600060208284031215613d7d57600080fd5b8135613d8881613d56565b9392505050565b60008083601f840112613da157600080fd5b5081356001600160401b03811115613db857600080fd5b602083019150836020828501011115613dd057600080fd5b9250929050565b80151581146110fd57600080fd5b60008060008060008060808789031215613dfe57600080fd5b8635613e0981613d56565b955060208701356001600160401b0380821115613e2557600080fd5b613e318a838b01613d8f565b909750955060408901359150613e4682613dd7565b90935060608801359080821115613e5c57600080fd5b50613e6989828a01613d8f565b979a9699509497509295939492505050565b60005b83811015613e96578181015183820152602001613e7e565b50506000910152565b60008151808452613eb7816020860160208601613e7b565b601f01601f19169290920160200192915050565b602081526000610dcb6020830184613e9f565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715613f1c57613f1c613ede565b604052919050565b60006001600160401b03821115613f3d57613f3d613ede565b50601f01601f191660200190565b600082601f830112613f5c57600080fd5b8135613f6f613f6a82613f24565b613ef4565b818152846020838601011115613f8457600080fd5b816020850160208301376000918101602001919091529392505050565b60008060408385031215613fb457600080fd5b8235613fbf81613d56565b915060208301356001600160401b03811115613fda57600080fd5b613fe685828601613f4b565b9150509250929050565b60008060006060848603121561400557600080fd5b833561401081613d56565b925060208401356001600160401b038082111561402c57600080fd5b61403887838801613f4b565b9350604086013591508082111561404e57600080fd5b5061405b86828701613f4b565b9150509250925092565b60006020828403121561407757600080fd5b81356001600160401b0381111561408d57600080fd5b610de284828501613f4b565b602081526140ad60208201835160ff169052565b600060208301516140c3604084018260ff169052565b506040830151606083015260608301516140e860808401826001600160a01b03169052565b5060808301516001600160e01b0319811660a08401525060a08301516101608060c085015261411b610180850183613e9f565b915060c085015160e085015260e0850151610100818187015280870151915050610120818187015280870151915050610140614161818701836001600160a01b03169052565b909501516001600160a01b031693019290925250919050565b60008060008060008060006080888a03121561419557600080fd5b87356141a081613d56565b965060208801356001600160401b03808211156141bc57600080fd5b6141c88b838c01613d8f565b909850965060408a01359150808211156141e157600080fd5b6141ed8b838c01613d8f565b909650945060608a013591508082111561420657600080fd5b506142138a828b01613d8f565b989b979a50959850939692959293505050565b6040815260006142396040830185613e9f565b8281036020840152611c778185613e9f565b60008060006040848603121561426057600080fd5b83356001600160401b0381111561427657600080fd5b61428286828701613d8f565b909790965060209590950135949350505050565b600080602083850312156142a957600080fd5b82356001600160401b03808211156142c057600080fd5b818501915085601f8301126142d457600080fd5b8135818111156142e357600080fd5b8660208260051b85010111156142f857600080fd5b60209290920196919550909350505050565b60008060008060008060a0878903121561432357600080fd5b86356001600160401b0381111561433957600080fd5b61434589828a01613d8f565b909750955050602087013561435981613d56565b93506040870135925060608701359150608087013561437781613d56565b809150509295509295509295565b6000806040838503121561439857600080fd5b50508035926020909101359150565b6000602082840312156143b957600080fd5b5035919050565b600080600080606085870312156143d657600080fd5b84356001600160401b038111156143ec57600080fd5b6143f887828801613d8f565b909550935050602085013561440c81613d56565b9396929550929360400135925050565b60008060008060006060868803121561443457600080fd5b853561443f81613d56565b945060208601356001600160401b038082111561445b57600080fd5b61446789838a01613d8f565b9096509450604088013591508082111561448057600080fd5b5061448d88828901613d8f565b969995985093965092949392505050565b600080604083850312156144b157600080fd5b82356144bc81613d56565b915060208301356144cc81613d56565b809150509250929050565b6000806000604084860312156144ec57600080fd5b8335925060208401356001600160401b0381111561450957600080fd5b61451586828701613d8f565b9497909650939450505050565b6000806020838503121561453557600080fd5b82356001600160401b0381111561454b57600080fd5b61455785828601613d8f565b90969095509350505050565b6020808252825182820181905260009190848201906040850190845b818110156145a45783516001600160a01b03168352928401929184019160010161457f565b50909695505050505050565b600080604083850312156145c357600080fd5b82356145ce81613d56565b946020939093013593505050565b6000602082840312156145ee57600080fd5b5051919050565b634e487b7160e01b600052601160045260246000fd5b81810381811115610dce57610dce6145f5565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052600160045260246000fd5b600082601f83011261465b57600080fd5b8151614669613f6a82613f24565b81815284602083860101111561467e57600080fd5b610de2826020830160208701613e7b565b6000602082840312156146a157600080fd5b81516001600160401b038111156146b757600080fd5b610de28482850161464a565b6000602082840312156146d557600080fd5b8151613d8881613dd7565b6001600160a01b039384168152919092166020820152604081019190915260600190565b8082018281126000831280158216821582161715614724576147246145f5565b505092915050565b600060ff821660ff8103614742576147426145f5565b60010192915050565b60006020828403121561475d57600080fd5b8151613d8881613d56565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b6000600182016147c8576147c86145f5565b5060010190565b600082516147e1818460208701613e7b565b9190910192915050565b60008261480857634e487b7160e01b600052601260045260246000fd5b500490565b80820180821115610dce57610dce6145f5565b6000806040838503121561483357600080fd5b82516001600160401b038082111561484a57600080fd5b6148568683870161464a565b9350602085015191508082111561486c57600080fd5b50613fe68582860161464a565b600080600080600060a0868803121561489157600080fd5b855194506020860151935060408601516148aa81613d56565b60608701519093506001600160e01b0319811681146148c857600080fd5b60808701519092506001600160401b038111156148e457600080fd5b6148f08882890161464a565b9150509295509295909350565b6000806000806080858703121561491357600080fd5b8451935060208501519250604085015161492c81613d56565b606086015190925061493d81613d56565b939692955090935050565b858152602081018590526001600160a01b03841660408201526001600160e01b03198316606082015260a06080820181905260009061498990830184613e9f565b979650505050505050565b60008235605e198336030181126147e157600080fd5b6000602082840312156149bc57600080fd5b813563ffffffff81168114613d8857600080fd5b6000808335601e198436030181126149e757600080fd5b8301803591506001600160401b03821115614a0157600080fd5b602001915036819003821315613dd057600080fd5b600080600060608486031215614a2b57600080fd5b8335614a3681613d56565b92506020840135614a4681613d56565b929592945050506040919091013590565b60008060408385031215614a6a57600080fd5b82356001600160401b0380821115614a8157600080fd5b614a8d86838701613f4b565b93506020850135915080821115614aa357600080fd5b50613fe685828601613f4b565b60608152604160608201527f6f72672e7375706572666c7569642d66696e616e63652e7375706572666c756960808201527f642e61707057686974654c697374696e672e726567697374726174696f6e4b6560a0820152607960f81b60c082015260018060a01b038316602082015260e060408201526000610de260e0830184613e9f565b600085516020614b488285838b01613e7b565b81840191508682528551614b6181838501848a01613e7b565b8551920191614b7581838501848901613e7b565b91909101019695505050505050565b6000816000190483118215151615614b9e57614b9e6145f5565b50029056fe608060405234801561001057600080fd5b5061022a806100206000396000f3fe6080604052600436106100225760003560e01c80634a0687ef1461003957610031565b366100315761002f610059565b005b61002f610059565b34801561004557600080fd5b5061002f6100543660046101c4565b61006b565b610069610064610171565b6101a0565b565b6001600160a01b0381166100c65760405162461bcd60e51b815260206004820152601760248201527f5555505350726f78793a207a65726f206164647265737300000000000000000060448201526064015b60405180910390fd5b60006100f07f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b6001600160a01b0316146101465760405162461bcd60e51b815260206004820152601e60248201527f5555505350726f78793a20616c726561647920696e697469616c697a6564000060448201526064016100bd565b61016e817f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc55565b50565b600061019b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5490565b905090565b3660008037600080366000845af43d6000803e8080156101bf573d6000f35b3d6000fd5b6000602082840312156101d657600080fd5b81356001600160a01b03811681146101ed57600080fd5b939250505056fea2646970667358221220d5a8e007f2080dfe84e95d171924fb4d89e3b402dfeaf170fb33ddf8acb5db0e64736f6c63430008100033a2646970667358221220af187faf3e5f1ddf4fbc57a06821f859abe766745f72d1c8988633d43c44f47064736f6c63430008100033