Overview
POL Balance
0 POL
POL Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
Automate
Compiler Version
v0.8.14+commit.80d49f37
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.14; import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import {Gelatofied} from "./vendor/gelato/Gelatofied.sol"; import {GelatoBytes} from "./vendor/gelato/GelatoBytes.sol"; import {Proxied} from "./vendor/proxy/EIP173/Proxied.sol"; import {AutomateStorage} from "./AutomateStorage.sol"; import {LibDataTypes} from "./libraries/LibDataTypes.sol"; import {LibEvents} from "./libraries/LibEvents.sol"; import {LibTaskId} from "./libraries/LibTaskId.sol"; import {LibTaskModule} from "./libraries/LibTaskModule.sol"; import {LibBypassModule} from "./libraries/LibBypassModule.sol"; import {IAutomate} from "./interfaces/IAutomate.sol"; /** * @notice Automate enables everyone to have Gelato monitor and execute transactions. * @notice ExecAddress refers to the contract that has the function which Gelato will call. * @notice Modules allow users to customise conditions and specifications when creating a task. */ //solhint-disable function-max-lines //solhint-disable no-empty-blocks contract Automate is Gelatofied, Proxied, AutomateStorage, IAutomate { using GelatoBytes for bytes; using EnumerableSet for EnumerableSet.Bytes32Set; // solhint-disable const-name-snakecase string public constant version = "7"; constructor(address payable _gelato) Gelatofied(_gelato) {} ///@inheritdoc IAutomate function createTask( address _execAddress, bytes calldata _execDataOrSelector, LibDataTypes.ModuleData calldata _moduleData, address _feeToken ) external override returns (bytes32 taskId) { address taskCreator; (taskCreator, _execAddress) = LibTaskModule.preCreateTask( msg.sender, _execAddress, taskModuleAddresses ); taskId = _createTask( taskCreator, _execAddress, _execDataOrSelector, _moduleData, _feeToken ); } ///@inheritdoc IAutomate function cancelTask(bytes32 _taskId) external { address _taskCreator = LibTaskModule.preCancelTask( _taskId, msg.sender, taskModuleAddresses ); _cancelTask(_taskCreator, _taskId); } ///@inheritdoc IAutomate function exec( address _taskCreator, address _execAddress, bytes memory _execData, LibDataTypes.ModuleData calldata _moduleData, uint256 _txFee, address _feeToken, bool _revertOnFailure ) external onlyGelato { bytes32 taskId = LibTaskId.getTaskId( _taskCreator, _execAddress, _execData.memorySliceSelector(), _moduleData, _feeToken ); require( _createdTasks[_taskCreator].contains(taskId), "Automate.exec: Task not found" ); fee = _txFee; feeToken = _feeToken; bool success = LibTaskModule.onExecTask( taskId, _taskCreator, _execAddress, _execData, _moduleData.modules, _revertOnFailure, taskModuleAddresses ); delete fee; delete feeToken; emit LibEvents.ExecSuccess( _txFee, _feeToken, _execAddress, _execData, taskId, success ); } ///@inheritdoc IAutomate function exec1Balance( address _taskCreator, address _execAddress, bytes memory _execData, LibDataTypes.ModuleData calldata _moduleData, Gelato1BalanceParam calldata _oneBalanceParam, bool _revertOnFailure ) external onlyGelato { bytes32 taskId = LibTaskId.getTaskId( _taskCreator, _execAddress, _execData.memorySliceSelector(), _moduleData, address(0) ); require( _createdTasks[_taskCreator].contains(taskId), "Automate.exec: Task not found" ); bool success = LibTaskModule.onExecTask( taskId, _taskCreator, _execAddress, _execData, _moduleData.modules, _revertOnFailure, taskModuleAddresses ); emit LibEvents.ExecSuccess( 0, address(0), _execAddress, _execData, taskId, success ); emit LogUseGelato1Balance( _oneBalanceParam.sponsor, _execAddress, _oneBalanceParam.feeToken, _oneBalanceParam.oneBalanceChainId, _oneBalanceParam.nativeToFeeTokenXRateNumerator, _oneBalanceParam.nativeToFeeTokenXRateDenominator, _oneBalanceParam.correlationId ); } function execBypassModuleSyncFee( address _taskCreator, address _execAddress, bytes32 _taskId, uint256 _txFee, address _feeToken, bytes memory _execData, bool _revertOnFailure, bool _singleExec ) external onlyGelato { require( _createdTasks[_taskCreator].contains(_taskId), "Automate.exec: Task not found" ); fee = _txFee; feeToken = _feeToken; bool success = LibBypassModule.onExecTask( _taskId, _taskCreator, _execAddress, _execData, _revertOnFailure, _singleExec, _createdTasks ); delete fee; delete feeToken; emit LibEvents.ExecBypassModuleSyncFeeSuccess( _taskId, _txFee, _feeToken, success ); } ///@inheritdoc IAutomate function execBypassModule( address _taskCreator, address _execAddress, bytes32 _taskId, bytes32 _correlationId, bytes memory _execData, bool _revertOnFailure, bool _singleExec ) external onlyGelato { require( _createdTasks[_taskCreator].contains(_taskId), "Automate.exec: Task not found" ); bool success = LibBypassModule.onExecTask( _taskId, _taskCreator, _execAddress, _execData, _revertOnFailure, _singleExec, _createdTasks ); emit LibEvents.ExecBypassModuleSuccess( _taskId, _correlationId, success ); } ///@inheritdoc IAutomate function setModule( LibDataTypes.Module[] calldata _modules, address[] calldata _moduleAddresses ) external onlyProxyAdmin { uint256 length = _modules.length; for (uint256 i; i < length; i++) { taskModuleAddresses[_modules[i]] = _moduleAddresses[i]; } } ///@inheritdoc IAutomate function getFeeDetails() external view returns (uint256, address) { return (fee, feeToken); } ///@inheritdoc IAutomate function getTaskIdsByUser(address _taskCreator) external view returns (bytes32[] memory) { bytes32[] memory taskIds = _createdTasks[_taskCreator].values(); return taskIds; } ///@inheritdoc IAutomate function getTaskId( address taskCreator, address execAddress, bytes4 execSelector, LibDataTypes.ModuleData memory moduleData, address feeToken ) external pure returns (bytes32 taskId) { taskId = LibTaskId.getTaskId( taskCreator, execAddress, execSelector, moduleData, feeToken ); } function _createTask( address _taskCreator, address _execAddress, bytes memory _execDataOrSelector, LibDataTypes.ModuleData memory _moduleData, address _feeToken ) private returns (bytes32 taskId) { taskId = LibTaskId.getTaskId( _taskCreator, _execAddress, _execDataOrSelector.memorySliceSelector(), _moduleData, _feeToken ); require( !_createdTasks[_taskCreator].contains(taskId), "Automate.createTask: Duplicate task" ); LibTaskModule.onCreateTask( taskId, _taskCreator, _execAddress, _execDataOrSelector, _moduleData, taskModuleAddresses ); _createdTasks[_taskCreator].add(taskId); emit LibEvents.TaskCreated( _taskCreator, _execAddress, _execDataOrSelector, _moduleData, _feeToken, taskId ); } function _cancelTask(address _taskCreator, bytes32 _taskId) private { require( _createdTasks[_taskCreator].contains(_taskId), "Automate.cancelTask: Task not found" ); _createdTasks[_taskCreator].remove(_taskId); emit LibEvents.TaskCancelled(_taskId, _taskCreator); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `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); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.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 functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol) pragma solidity ^0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. */ library EnumerableSet { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping(bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; if (lastIndex != toDeleteIndex) { bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex } // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { return set._values[index]; } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function _values(Set storage set) private view returns (bytes32[] memory) { return set._values; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { return _values(set._inner); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(AddressSet storage set) internal view returns (address[] memory) { bytes32[] memory store = _values(set._inner); address[] memory result; assembly { result := store } return result; } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } /** * @dev Return the entire set in an array * * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that * this function has an unbounded cost, and using it as part of a state-changing function may render the function * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. */ function values(UintSet storage set) internal view returns (uint256[] memory) { bytes32[] memory store = _values(set._inner); uint256[] memory result; assembly { result := store } return result; } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.12; import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import {LibDataTypes} from "./libraries/LibDataTypes.sol"; /** * @notice Storage layout of Automate smart contract. */ // solhint-disable max-states-count abstract contract AutomateStorage { mapping(bytes32 => address) public taskCreator; ///@dev Deprecated mapping(bytes32 => address) public execAddresses; ///@dev Deprecated mapping(address => EnumerableSet.Bytes32Set) internal _createdTasks; uint256 public fee; address public feeToken; ///@dev Appended State mapping(bytes32 => LibDataTypes.Time) public timedTask; ///@dev Deprecated mapping(LibDataTypes.Module => address) public taskModuleAddresses; mapping(bytes32 => uint256) public nonce1Balance; ///@dev Deprecated }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.12; import {GelatoBytes} from "../vendor/gelato/GelatoBytes.sol"; // solhint-disable private-vars-leading-underscore // solhint-disable func-visibility function _call( address _add, bytes memory _data, uint256 _value, bool _revertOnFailure, string memory _tracingInfo ) returns (bool success, bytes memory returnData) { (success, returnData) = _add.call{value: _value}(_data); if (!success && _revertOnFailure) GelatoBytes.revertWithError(returnData, _tracingInfo); } function _delegateCall( address _add, bytes memory _data, string memory _tracingInfo ) returns (bool success, bytes memory returnData) { (success, returnData) = _add.delegatecall(_data); if (!success) GelatoBytes.revertWithError(returnData, _tracingInfo); }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.12; import { SafeERC20, IERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; address constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; // solhint-disable private-vars-leading-underscore // solhint-disable func-visibility function _transfer( address payable _to, address _paymentToken, uint256 _amount ) { if (_paymentToken == ETH) { (bool success, ) = _to.call{value: _amount}(""); require(success, "_transfer: ETH transfer failed"); } else { SafeERC20.safeTransfer(IERC20(_paymentToken), _to, _amount); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {LibDataTypes} from "../libraries/LibDataTypes.sol"; import {IGelato1Balance} from "./IGelato1Balance.sol"; // solhint-disable max-line-length interface IAutomate is IGelato1Balance { /** * @notice Initiates a task with conditions which Gelato will monitor and execute when conditions are met. * * @param execAddress Address of contract that should be called by Gelato. * @param execData Execution data to be called with / function selector if execution data is yet to be determined. * @param moduleData Conditional modules that will be used. {See LibDataTypes-ModuleData} * @param feeToken Address of token to be used as payment. Use address(0) if Gelato 1Balance is being used, 0xeeeeee... for ETH or native tokens. * * @return taskId Unique hash of the task created. */ function createTask( address execAddress, bytes calldata execData, LibDataTypes.ModuleData calldata moduleData, address feeToken ) external returns (bytes32 taskId); /** * @notice Terminates a task that was created and Gelato can no longer execute it. * * @param taskId Unique hash of the task that is being cancelled. {See LibTaskId-getTaskId} */ function cancelTask(bytes32 taskId) external; /** * @notice Execution API called by Gelato, using Sync Fee as fee payment method * * @param taskCreator The address which created the task. * @param execAddress Address of contract that should be called by Gelato. * @param execData Execution data to be called with / function selector if execution data is yet to be determined. * @param moduleData Conditional modules that will be used. {See LibDataTypes-ModuleData} * @param txFee Fee paid to Gelato for execution, transfered to Gelato.feeCollector(). * @param feeToken Token used to pay for the execution. ETH = 0xeeeeee... * @param revertOnFailure To revert or not if call to execAddress fails. (Used for off-chain simulations) */ function exec( address taskCreator, address execAddress, bytes memory execData, LibDataTypes.ModuleData calldata moduleData, uint256 txFee, address feeToken, bool revertOnFailure ) external; /** * @notice Execution API called by Gelato, using Gelato 1Balance as fee payment method. * * @param taskCreator The address which created the task. * @param execAddress Address of contract that should be called by Gelato. * @param execData Execution data to be called with / function selector if execution data is yet to be determined. * @param moduleData Conditional modules that will be used. {See LibDataTypes-ModuleData} * @param oneBalanceParam Parameters required for fee payment with Gelato 1Balance. * @param revertOnFailure To revert or not if call to execAddress fails. (Used for off-chain simulations) */ function exec1Balance( address taskCreator, address execAddress, bytes memory execData, LibDataTypes.ModuleData calldata moduleData, Gelato1BalanceParam calldata oneBalanceParam, bool revertOnFailure ) external; /** * @notice Execution API called by Gelato, using Gelato 1Balance as fee payment method. * * @param taskCreator The address which created the task. * @param execAddress Address of contract that should be called by Gelato. * @param taskId Unique hash of the task. * @param correlationId Id of the execution to be used for 1Balance settlement. * @param execData Execution data to be called with / function selector if execution data is yet to be determined. * @param revertOnFailure To revert or not if call to execAddress fails. (Used for off-chain simulations) * @param singleExec If the task is a SingleExec task. If true, task will be cancelled after execution. */ function execBypassModule( address taskCreator, address execAddress, bytes32 taskId, bytes32 correlationId, bytes memory execData, bool revertOnFailure, bool singleExec ) external; /** * @notice Execution API called by Gelato, using Gelato Sync fee as fee payment method. * * @param taskCreator The address which created the task. * @param execAddress Address of contract that should be called by Gelato. * @param taskId Unique hash of the task. * @param txFee Fee paid to Gelato for execution, transfered to Gelato.feeCollector(). * @param feeToken Token used to pay for the execution. ETH = 0xeeeeee... * @param execData Execution data to be called with / function selector if execution data is yet to be determined. * @param revertOnFailure To revert or not if call to execAddress fails. (Used for off-chain simulations) * @param singleExec If the task is a SingleExec task. If true, task will be cancelled after execution. */ function execBypassModuleSyncFee( address taskCreator, address execAddress, bytes32 taskId, uint256 txFee, address feeToken, bytes memory execData, bool revertOnFailure, bool singleExec ) external; /** * @notice Sets the address of task modules. Only callable by proxy admin. * * @param modules List of modules to be set * @param moduleAddresses List of addresses for respective modules. */ function setModule( LibDataTypes.Module[] calldata modules, address[] calldata moduleAddresses ) external; /** * @notice Helper function to query fee and feeToken to be used for payment. (For executions which pays itself) * * @return uint256 Fee amount to be paid. * @return address Token to be paid. (Determined and passed by taskCreator during createTask) */ function getFeeDetails() external view returns (uint256, address); /** * @notice Helper func to query all open tasks by a task creator. * * @param taskCreator Address of task creator to query. * * @return bytes32[] List of taskIds created. */ function getTaskIdsByUser(address taskCreator) external view returns (bytes32[] memory); /** * @notice Helper function to compute task id with module arguments * * @param taskCreator The address which created the task. * @param execAddress Address of contract that will be called by Gelato. * @param execSelector Signature of the function which will be called by Gelato. * @param moduleData Conditional modules that will be used. {See LibDataTypes-ModuleData} * @param feeToken Address of token to be used as payment. Use address(0) if Gelato 1Balance is being used, 0xeeeeee... for ETH or native tokens. */ function getTaskId( address taskCreator, address execAddress, bytes4 execSelector, LibDataTypes.ModuleData memory moduleData, address feeToken ) external pure returns (bytes32 taskId); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IGelato1Balance { struct Gelato1BalanceParam { address sponsor; address feeToken; uint256 oneBalanceChainId; uint256 nativeToFeeTokenXRateNumerator; uint256 nativeToFeeTokenXRateDenominator; bytes32 correlationId; } event LogUseGelato1Balance( address indexed sponsor, address indexed target, address indexed feeToken, uint256 oneBalanceChainId, uint256 nativeToFeeTokenXRateNumerator, uint256 nativeToFeeTokenXRateDenominator, bytes32 correlationId ); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.12; // solhint-disable max-line-length interface ITaskModule { /** * @notice Called before generating taskId. * @dev Modules can override execAddress or taskCreator. {See ProxyModule-preCreateTask} * * @param taskCreator The address which created the task. * @param execAddress Address of contract that should be called. * * @return address Overriden or original taskCreator. * @return address Overriden or original execAddress. */ function preCreateTask(address taskCreator, address execAddress) external returns (address, address); /** * @notice Initiates task module whenever `createTask` is being called. * * @param taskId Unique hash of the task created. * @param taskCreator The address which created the task. * @param execAddress Address of contract that should be called. * @param execData Execution data to be called with / function selector if execution data is yet to be determined. * @param initModuleArg Encoded arguments for module if any. */ function onCreateTask( bytes32 taskId, address taskCreator, address execAddress, bytes calldata execData, bytes calldata initModuleArg ) external; /** * @notice Called before taskId is removed from _createdTasks[]. * @dev Modules can override taskCreator. * * @param taskId Unique hash of the task created. * @param taskCreator The address which created the task. * * @return address Overriden or original taskCreator. */ function preCancelTask(bytes32 taskId, address taskCreator) external returns (address); /** * @notice Called during `exec` and before execAddress is called. * * @param taskId Unique hash of the task created. * @param taskCreator The address which created the task. * @param execAddress Address of contract that should be called. * @param execData Execution data to be called with / function selector if execution data is yet to be determined. * * @return address Overriden or original execution address. * @return bytes Overriden or original execution data. */ function preExecCall( bytes32 taskId, address taskCreator, address execAddress, bytes calldata execData ) external returns (address, bytes memory); /** * @notice Called during `exec` and after execAddress is called. * * @param taskId Unique hash of the task created. * @param taskCreator The address which created the task. * @param execAddress Address of contract that should be called. * @param execData Execution data to be called with / function selector if execution data is yet to be determined. */ function postExecCall( bytes32 taskId, address taskCreator, address execAddress, bytes calldata execData ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.12; import { EnumerableSet } from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; import {_call, _delegateCall} from "../functions/FExec.sol"; import {LibDataTypes} from "./LibDataTypes.sol"; import {LibEvents} from "./LibEvents.sol"; import {LibTaskModule} from "./LibTaskModule.sol"; import {LibTaskModuleConfig} from "./LibTaskModuleConfig.sol"; import {ITaskModule} from "../interfaces/ITaskModule.sol"; // solhint-disable function-max-lines /// @notice Simplified library for task executions library LibBypassModule { using EnumerableSet for EnumerableSet.Bytes32Set; using LibTaskModuleConfig for LibDataTypes.Module; /** * @notice Delegate calls SingleExecModule on exec for single exec tasks. * * @param _taskId Unique hash of the task. {See LibTaskId-getTaskId} * @param _taskCreator Address which created the task. * @param _execAddress Address of contract that will be called by Gelato. * @param _execData Execution data to be called with / function selector. * @param _revertOnFailure To revert or not if call to execAddress fails. * @param _singleExec If task is a single exec task. * @param _createdTasks The storage reference of owner to the taskIds created mapping. */ function onExecTask( bytes32 _taskId, address _taskCreator, address _execAddress, bytes memory _execData, bool _revertOnFailure, bool _singleExec, mapping(address => EnumerableSet.Bytes32Set) storage _createdTasks ) internal returns (bool callSuccess) { (callSuccess, ) = _call( _execAddress, abi.encodePacked(_execData, _taskCreator), 0, _revertOnFailure, "Automate.exec: " ); if (_singleExec) { _createdTasks[_taskCreator].remove(_taskId); emit LibEvents.TaskCancelled(_taskId, _taskCreator); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.12; // solhint-disable max-line-length library LibDataTypes { /** * @notice Whitelisted modules that are available for users to customise conditions and specifications of their tasks. * * @param RESOLVER Use dynamic condition & input data for execution. {See ResolverModule.sol} * @param DEPRECATED_TIME deprecated * @param PROXY Creates a dedicated caller (msg.sender) to be used when executing the task. {See ProxyModule.sol} * @param SINGLE_EXEC Task is cancelled after one execution. {See SingleExecModule.sol} * @param WEB3_FUNCTION Use off-chain condition & input data for execution. {See Web3FunctionModule.sol} * @param TRIGGER Repeated execution of task ata a specified timing and interval or cron. {See TriggerModule.sol} */ enum Module { RESOLVER, DEPRECATED_TIME, // @deprecated PROXY, SINGLE_EXEC, WEB3_FUNCTION, TRIGGER } /** * @notice Struct to contain modules and their relative arguments that are used for task creation. * * @param modules List of selected modules. * @param args Arguments of modules if any. Pass "0x" for modules which does not require args {See encodeModuleArg} */ struct ModuleData { Module[] modules; bytes[] args; } /** * @notice Struct for time module. * * @param nextExec Time when the next execution should occur. * @param interval Time interval between each execution. */ struct Time { uint128 nextExec; uint128 interval; } /** * @notice Types of trigger * * @param TIME Time triggered tasks, starting at a specific time and triggered intervally * @param CRON Cron triggered tasks, triggered according to the cron conditions */ enum TriggerType { TIME, CRON, EVENT, BLOCK } /** * @notice Struct for trigger module * * @param triggerType Type of the trigger * @param triggerConfig Trigger configuration that shuold be parsed according to triggerType */ struct TriggerModuleData { TriggerType triggerType; bytes triggerConfig; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.12; import {LibDataTypes} from "./LibDataTypes.sol"; library LibEvents { /** * @notice Emitted when `createTask` is called. * * @param taskCreator The address which created the task. * @param execAddress Address of contract that is called by Gelato. * @param execDataOrSelector Execution data / function selector. * @param moduleData Conditional modules used. {See LibDataTypes-ModuleData} * @param feeToken Token used to pay for the execution. ETH = 0xeeeeee... * @param taskId Unique hash of the task. {See LibTaskId-getTaskId} */ event TaskCreated( address indexed taskCreator, address indexed execAddress, bytes execDataOrSelector, LibDataTypes.ModuleData moduleData, address feeToken, bytes32 indexed taskId ); /** * @notice Emitted when `cancelTask` is called. * * @param taskId Unique hash of the task. {See LibTaskId-getTaskId} * @param taskCreator The address which owned the task. */ event TaskCancelled(bytes32 taskId, address taskCreator); /** * @notice Emitted when `exec` is called. * * @param txFee Fee paid to Gelato for execution * @param feeToken Token used to pay for the execution. ETH = 0xeeeeee... * @param execAddress Address of contract that will be called by Gelato. * @param execData Execution data / function selector. * @param taskId Unique hash of the task. {See LibTaskId-getTaskId} * @param callSuccess Status of the call to execAddress. */ event ExecSuccess( uint256 indexed txFee, address indexed feeToken, address indexed execAddress, bytes execData, bytes32 taskId, bool callSuccess ); /** * @notice Emitted when `execBypassModule` is called. * * @param taskId Unique hash of the task. {See LibTaskId-getTaskId} * @param correlationId Id of the execution to be used for 1Balance settlement. * @param callSuccess Status of the call to execAddress. */ event ExecBypassModuleSuccess( bytes32 taskId, bytes32 correlationId, bool callSuccess ); /** * @notice Emitted when `execBypassModuleSyncFee` is called. * * @param taskId Unique hash of the task. {See LibTaskId-getTaskId} * @param txFee Fee paid to Gelato for execution * @param feeToken Token used to pay for the execution. ETH = 0xeeeeee... * @param callSuccess Status of the call to execAddress. */ event ExecBypassModuleSyncFeeSuccess( bytes32 taskId, uint256 txFee, address feeToken, bool callSuccess ); }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.0; import {LibDataTypes} from "./LibDataTypes.sol"; /** * @notice Library to compute taskId of tasks. */ // solhint-disable max-line-length library LibTaskId { /** * @notice Returns taskId of taskCreator. * * @param taskCreator The address which created the task. * @param execAddress Address of contract that will be called by Gelato. * @param execSelector Signature of the function which will be called by Gelato. * @param moduleData Conditional modules that will be used. {See LibDataTypes-ModuleData} * @param feeToken Address of token to be used as payment. Use address(0) if Gelato 1Balance is being used, 0xeeeeee... for ETH or native tokens. */ function getTaskId( address taskCreator, address execAddress, bytes4 execSelector, LibDataTypes.ModuleData memory moduleData, address feeToken ) internal pure returns (bytes32 taskId) { taskId = keccak256( abi.encode( taskCreator, execAddress, execSelector, moduleData, feeToken ) ); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.12; import {_call, _delegateCall} from "../functions/FExec.sol"; import {LibDataTypes} from "./LibDataTypes.sol"; import {LibTaskModuleConfig} from "./LibTaskModuleConfig.sol"; import {ITaskModule} from "../interfaces/ITaskModule.sol"; // solhint-disable function-max-lines /// @notice Library to call task modules on task creation and execution. library LibTaskModule { using LibTaskModuleConfig for LibDataTypes.Module; /** * @notice Delegate calls task modules before generating taskId. * * @param _execAddress Address of contract that will be called by Gelato. * @param _taskCreator The address which created the task. * @param taskModuleAddresses The storage reference to the mapping of modules to their address. */ function preCreateTask( address _taskCreator, address _execAddress, mapping(LibDataTypes.Module => address) storage taskModuleAddresses ) internal returns (address, address) { uint256 length = uint256(type(LibDataTypes.Module).max) + 1; for (uint256 i; i < length; i++) { LibDataTypes.Module module = LibDataTypes.Module(i); if (!module.requirePreCreate()) continue; address moduleAddress = taskModuleAddresses[module]; _moduleInitialised(moduleAddress); bytes memory delegatecallData = abi.encodeWithSelector( ITaskModule.preCreateTask.selector, _taskCreator, _execAddress ); (, bytes memory returnData) = _delegateCall( moduleAddress, delegatecallData, "Automate.preCreateTask: " ); (_taskCreator, _execAddress) = abi.decode( returnData, (address, address) ); } return (_taskCreator, _execAddress); } /** * @notice Delegate calls task modules on create task to initialise them. * * @param _taskId Unique hash of the task. {See LibTaskId-getTaskId} * @param _taskCreator The address which created the task. * @param _execAddress Address of contract that will be called by Gelato. * @param _execData Execution data to be called with / function selector. * @param _moduleData Modules that will be used for the task. {See LibDataTypes-ModuleData} * @param taskModuleAddresses The storage reference to the mapping of modules to their address. */ function onCreateTask( bytes32 _taskId, address _taskCreator, address _execAddress, bytes memory _execData, LibDataTypes.ModuleData memory _moduleData, mapping(LibDataTypes.Module => address) storage taskModuleAddresses ) internal { uint256 length = _moduleData.modules.length; _validModules(_moduleData.modules); for (uint256 i; i < length; i++) { LibDataTypes.Module module = _moduleData.modules[i]; if (!module.requireOnCreate()) continue; address moduleAddress = taskModuleAddresses[module]; _moduleInitialised(moduleAddress); bytes memory delegatecallData = abi.encodeWithSelector( ITaskModule.onCreateTask.selector, _taskId, _taskCreator, _execAddress, _execData, _moduleData.args[i] ); _delegateCall( moduleAddress, delegatecallData, "Automate.onCreateTask: " ); } } /** * @notice Delegate calls task modules before removing task. * * @param _taskId Unique hash of the task. {See LibTaskId-getTaskId} * @param _taskCreator The address which created the task. * @param taskModuleAddresses The storage reference to the mapping of modules to their address. */ function preCancelTask( bytes32 _taskId, address _taskCreator, mapping(LibDataTypes.Module => address) storage taskModuleAddresses ) internal returns (address) { uint256 length = uint256(type(LibDataTypes.Module).max); for (uint256 i; i <= length; i++) { LibDataTypes.Module module = LibDataTypes.Module(i); if (!module.requirePreCancel()) continue; address moduleAddress = taskModuleAddresses[module]; _moduleInitialised(moduleAddress); bytes memory delegatecallData = abi.encodeWithSelector( ITaskModule.preCancelTask.selector, _taskId, _taskCreator ); (, bytes memory returnData) = _delegateCall( moduleAddress, delegatecallData, "Automate.preCancelTask: " ); (_taskCreator) = abi.decode(returnData, (address)); } return _taskCreator; } /** * @notice Delegate calls task modules on exec. * * @param _taskId Unique hash of the task. {See LibTaskId-getTaskId} * @param _taskCreator Address which created the task. * @param _execAddress Address of contract that will be called by Gelato. * @param _execData Execution data to be called with / function selector. * @param _modules Modules that is used for the task. {See LibDataTypes-Module} * @param _revertOnFailure To revert or not if call to execAddress fails. * @param taskModuleAddresses The storage reference to the mapping of modules to their address. */ function onExecTask( bytes32 _taskId, address _taskCreator, address _execAddress, bytes memory _execData, LibDataTypes.Module[] memory _modules, bool _revertOnFailure, mapping(LibDataTypes.Module => address) storage taskModuleAddresses ) internal returns (bool callSuccess) { address[] memory moduleAddresses = _getModuleAddresses( _modules, taskModuleAddresses ); (_execAddress, _execData) = preExecCall( _taskId, _taskCreator, _execAddress, _execData, _modules, moduleAddresses ); (callSuccess, ) = _call( _execAddress, abi.encodePacked(_execData, _taskCreator), 0, _revertOnFailure, "Automate.exec: " ); postExecCall( _taskId, _taskCreator, _execAddress, _execData, _modules, moduleAddresses ); } function preExecCall( bytes32 _taskId, address _taskCreator, address _execAddress, bytes memory _execData, LibDataTypes.Module[] memory _modules, address[] memory _moduleAddresses ) internal returns (address, bytes memory) { uint256 length = _modules.length; for (uint256 i; i < length; i++) { if (!_modules[i].requirePreExec()) continue; bytes memory delegatecallData = abi.encodeWithSelector( ITaskModule.preExecCall.selector, _taskId, _taskCreator, _execAddress, _execData ); (, bytes memory returnData) = _delegateCall( _moduleAddresses[i], delegatecallData, "Automate.preExecCall: " ); (_execAddress, _execData) = abi.decode( returnData, (address, bytes) ); } return (_execAddress, _execData); } function postExecCall( bytes32 _taskId, address _taskCreator, address _execAddress, bytes memory _execData, LibDataTypes.Module[] memory _modules, address[] memory _moduleAddresses ) internal { uint256 length = _moduleAddresses.length; for (uint256 i; i < length; i++) { if (!_modules[i].requirePostExec()) continue; bytes memory delegatecallData = abi.encodeWithSelector( ITaskModule.postExecCall.selector, _taskId, _taskCreator, _execAddress, _execData ); _delegateCall( _moduleAddresses[i], delegatecallData, "Automate.postExecCall: " ); } } function _getModuleAddresses( LibDataTypes.Module[] memory _modules, mapping(LibDataTypes.Module => address) storage taskModuleAddresses ) private view returns (address[] memory) { uint256 length = _modules.length; address[] memory moduleAddresses = new address[](length); for (uint256 i; i < length; i++) { moduleAddresses[i] = taskModuleAddresses[_modules[i]]; } return moduleAddresses; } function _moduleInitialised(address _moduleAddress) private pure { require( _moduleAddress != address(0), "Automate._moduleInitialised: Not init" ); } /** * @dev * - No duplicate modules * - No deprecated TIME * - No RESOLVER && WEB3_FUNCTION * - PROXY is required */ function _validModules(LibDataTypes.Module[] memory _modules) private pure { uint256 length = _modules.length; uint256 existsLength = uint256(type(LibDataTypes.Module).max) + 1; bool[] memory exists = new bool[](existsLength); for (uint256 i = 0; i < length; i++) { if (i > 0) { require( _modules[i] > _modules[i - 1], "Automate._validModules: Asc only" ); } exists[uint256(_modules[i])] = true; } require( !exists[uint256(LibDataTypes.Module.DEPRECATED_TIME)], "Automate._validModules: TIME is deprecated" ); require( !(exists[uint256(LibDataTypes.Module.RESOLVER)] && exists[uint256(LibDataTypes.Module.WEB3_FUNCTION)]), "Automate._validModules: Only RESOLVER or WEB3_FUNCTION" ); require( exists[uint256(LibDataTypes.Module.PROXY)], "Automate._validModules: PROXY is required" ); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.12; import {LibDataTypes} from "./LibDataTypes.sol"; /** * @notice Library to determine wether to call task modules to reduce unnecessary calls. */ library LibTaskModuleConfig { function requirePreCreate(LibDataTypes.Module _module) internal pure returns (bool) { if (_module == LibDataTypes.Module.PROXY) return true; return false; } function requirePreCancel(LibDataTypes.Module _module) internal pure returns (bool) { if (_module == LibDataTypes.Module.PROXY) return true; return false; } function requireOnCreate(LibDataTypes.Module _module) internal pure returns (bool) { if (_module == LibDataTypes.Module.PROXY) return true; return false; } function requirePreExec(LibDataTypes.Module _module) internal pure returns (bool) { if (_module == LibDataTypes.Module.PROXY) return true; return false; } function requirePostExec(LibDataTypes.Module _module) internal pure returns (bool) { if (_module == LibDataTypes.Module.SINGLE_EXEC) return true; return false; } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.12; library GelatoBytes { function calldataSliceSelector(bytes calldata _bytes) internal pure returns (bytes4 selector) { selector = _bytes[0] | (bytes4(_bytes[1]) >> 8) | (bytes4(_bytes[2]) >> 16) | (bytes4(_bytes[3]) >> 24); } function memorySliceSelector(bytes memory _bytes) internal pure returns (bytes4 selector) { selector = _bytes[0] | (bytes4(_bytes[1]) >> 8) | (bytes4(_bytes[2]) >> 16) | (bytes4(_bytes[3]) >> 24); } function revertWithError(bytes memory _bytes, string memory _tracingInfo) internal pure { // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err if (_bytes.length % 32 == 4) { bytes4 selector; assembly { selector := mload(add(0x20, _bytes)) } if (selector == 0x08c379a0) { // Function selector for Error(string) assembly { _bytes := add(_bytes, 68) } revert(string(abi.encodePacked(_tracingInfo, string(_bytes)))); } else { revert( string(abi.encodePacked(_tracingInfo, "NoErrorSelector")) ); } } else { revert( string(abi.encodePacked(_tracingInfo, "UnexpectedReturndata")) ); } } function returnError(bytes memory _bytes, string memory _tracingInfo) internal pure returns (string memory) { // 68: 32-location, 32-length, 4-ErrorSelector, UTF-8 err if (_bytes.length % 32 == 4) { bytes4 selector; assembly { selector := mload(add(0x20, _bytes)) } if (selector == 0x08c379a0) { // Function selector for Error(string) assembly { _bytes := add(_bytes, 68) } return string(abi.encodePacked(_tracingInfo, string(_bytes))); } else { return string(abi.encodePacked(_tracingInfo, "NoErrorSelector")); } } else { return string(abi.encodePacked(_tracingInfo, "UnexpectedReturndata")); } } }
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.12; import { SafeERC20, IERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import {_transfer, ETH} from "../../functions/FUtils.sol"; abstract contract Gelatofied { address payable public immutable gelato; modifier gelatofy(uint256 _amount, address _paymentToken) { require(msg.sender == gelato, "Gelatofied: Only gelato"); _; _transfer(gelato, _paymentToken, _amount); } modifier onlyGelato() { require(msg.sender == gelato, "Gelatofied: Only gelato"); _; } constructor(address payable _gelato) { gelato = _gelato; } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.12; abstract contract Proxied { /// @notice to be used by initialisation / postUpgrade function so that only the proxy's admin can execute them /// It also allows these functions to be called inside a contructor /// even if the contract is meant to be used without proxy modifier proxied() { address proxyAdminAddress = _proxyAdmin(); // With hardhat-deploy proxies // the proxyAdminAddress is zero only for the implementation contract // if the implementation contract want to be used as a standalone/immutable contract // it simply has to execute the `proxied` function // This ensure the proxyAdminAddress is never zero post deployment // And allow you to keep the same code for both proxied contract and immutable contract if (proxyAdminAddress == address(0)) { // ensure can not be called twice when used outside of proxy : no admin // solhint-disable-next-line security/no-inline-assembly assembly { sstore( 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF ) } } else { require(msg.sender == proxyAdminAddress); } _; } modifier onlyProxyAdmin() { require(msg.sender == _proxyAdmin(), "NOT_AUTHORIZED"); _; } function _proxyAdmin() internal view returns (address adminAddress) { // solhint-disable-next-line security/no-inline-assembly assembly { adminAddress := sload( 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103 ) } } }
{ "evmVersion": "london", "libraries": {}, "metadata": { "bytecodeHash": "ipfs", "useLiteralContent": true }, "optimizer": { "enabled": false, "runs": 200 }, "remappings": [], "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address payable","name":"_gelato","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sponsor","type":"address"},{"indexed":true,"internalType":"address","name":"target","type":"address"},{"indexed":true,"internalType":"address","name":"feeToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"oneBalanceChainId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"nativeToFeeTokenXRateNumerator","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"nativeToFeeTokenXRateDenominator","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"correlationId","type":"bytes32"}],"name":"LogUseGelato1Balance","type":"event"},{"inputs":[{"internalType":"bytes32","name":"_taskId","type":"bytes32"}],"name":"cancelTask","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_execAddress","type":"address"},{"internalType":"bytes","name":"_execDataOrSelector","type":"bytes"},{"components":[{"internalType":"enum LibDataTypes.Module[]","name":"modules","type":"uint8[]"},{"internalType":"bytes[]","name":"args","type":"bytes[]"}],"internalType":"struct LibDataTypes.ModuleData","name":"_moduleData","type":"tuple"},{"internalType":"address","name":"_feeToken","type":"address"}],"name":"createTask","outputs":[{"internalType":"bytes32","name":"taskId","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_taskCreator","type":"address"},{"internalType":"address","name":"_execAddress","type":"address"},{"internalType":"bytes","name":"_execData","type":"bytes"},{"components":[{"internalType":"enum LibDataTypes.Module[]","name":"modules","type":"uint8[]"},{"internalType":"bytes[]","name":"args","type":"bytes[]"}],"internalType":"struct LibDataTypes.ModuleData","name":"_moduleData","type":"tuple"},{"internalType":"uint256","name":"_txFee","type":"uint256"},{"internalType":"address","name":"_feeToken","type":"address"},{"internalType":"bool","name":"_revertOnFailure","type":"bool"}],"name":"exec","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_taskCreator","type":"address"},{"internalType":"address","name":"_execAddress","type":"address"},{"internalType":"bytes","name":"_execData","type":"bytes"},{"components":[{"internalType":"enum LibDataTypes.Module[]","name":"modules","type":"uint8[]"},{"internalType":"bytes[]","name":"args","type":"bytes[]"}],"internalType":"struct LibDataTypes.ModuleData","name":"_moduleData","type":"tuple"},{"components":[{"internalType":"address","name":"sponsor","type":"address"},{"internalType":"address","name":"feeToken","type":"address"},{"internalType":"uint256","name":"oneBalanceChainId","type":"uint256"},{"internalType":"uint256","name":"nativeToFeeTokenXRateNumerator","type":"uint256"},{"internalType":"uint256","name":"nativeToFeeTokenXRateDenominator","type":"uint256"},{"internalType":"bytes32","name":"correlationId","type":"bytes32"}],"internalType":"struct IGelato1Balance.Gelato1BalanceParam","name":"_oneBalanceParam","type":"tuple"},{"internalType":"bool","name":"_revertOnFailure","type":"bool"}],"name":"exec1Balance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"execAddresses","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_taskCreator","type":"address"},{"internalType":"address","name":"_execAddress","type":"address"},{"internalType":"bytes32","name":"_taskId","type":"bytes32"},{"internalType":"bytes32","name":"_correlationId","type":"bytes32"},{"internalType":"bytes","name":"_execData","type":"bytes"},{"internalType":"bool","name":"_revertOnFailure","type":"bool"},{"internalType":"bool","name":"_singleExec","type":"bool"}],"name":"execBypassModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_taskCreator","type":"address"},{"internalType":"address","name":"_execAddress","type":"address"},{"internalType":"bytes32","name":"_taskId","type":"bytes32"},{"internalType":"uint256","name":"_txFee","type":"uint256"},{"internalType":"address","name":"_feeToken","type":"address"},{"internalType":"bytes","name":"_execData","type":"bytes"},{"internalType":"bool","name":"_revertOnFailure","type":"bool"},{"internalType":"bool","name":"_singleExec","type":"bool"}],"name":"execBypassModuleSyncFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"fee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"feeToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gelato","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFeeDetails","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"taskCreator","type":"address"},{"internalType":"address","name":"execAddress","type":"address"},{"internalType":"bytes4","name":"execSelector","type":"bytes4"},{"components":[{"internalType":"enum LibDataTypes.Module[]","name":"modules","type":"uint8[]"},{"internalType":"bytes[]","name":"args","type":"bytes[]"}],"internalType":"struct LibDataTypes.ModuleData","name":"moduleData","type":"tuple"},{"internalType":"address","name":"feeToken","type":"address"}],"name":"getTaskId","outputs":[{"internalType":"bytes32","name":"taskId","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_taskCreator","type":"address"}],"name":"getTaskIdsByUser","outputs":[{"internalType":"bytes32[]","name":"","type":"bytes32[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"nonce1Balance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum LibDataTypes.Module[]","name":"_modules","type":"uint8[]"},{"internalType":"address[]","name":"_moduleAddresses","type":"address[]"}],"name":"setModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"taskCreator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum LibDataTypes.Module","name":"","type":"uint8"}],"name":"taskModuleAddresses","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"timedTask","outputs":[{"internalType":"uint128","name":"nextExec","type":"uint128"},{"internalType":"uint128","name":"interval","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60a06040523480156200001157600080fd5b5060405162004a7938038062004a798339818101604052810190620000379190620000de565b808073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1681525050505062000110565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620000a68262000079565b9050919050565b620000b88162000099565b8114620000c457600080fd5b50565b600081519050620000d881620000ad565b92915050565b600060208284031215620000f757620000f662000074565b5b60006200010784828501620000c7565b91505092915050565b60805161493162000148600039600081816104710152818161072e015281816107ab01528181610a890152610e3701526149316000f3fe608060405234801561001057600080fd5b50600436106101215760003560e01c806380381407116100ad578063b81cd86611610071578063b81cd8661461032f578063cd3d4fb914610360578063ddca3f4314610390578063e1d173a9146103ae578063ee8ca3b5146103ca57610121565b8063803814071461028c578063813785e6146102a8578063abf26d55146102c4578063ac21631a146102e0578063b810c6361461031057610121565b80633323b467116100f45780633323b467146101d257806354fd4d5014610202578063573ea57514610220578063647846a51461023e5780636d2dd29f1461025c57610121565b80630407145c146101265780632e6e0bd01461015657806330a9fe6a146101865780633140576e146101a2575b600080fd5b610140600480360381019061013b9190612a90565b6103e6565b60405161014d9190612b85565b60405180910390f35b610170600480360381019061016b9190612bd3565b61043c565b60405161017d9190612c0f565b60405180910390f35b6101a0600480360381019061019b9190612dde565b61046f565b005b6101bc60048036038101906101b79190613168565b61065c565b6040516101c9919061320e565b60405180910390f35b6101ec60048036038101906101e791906132a8565b610676565b6040516101f9919061320e565b60405180910390f35b61020a6106f3565b60405161021791906133d4565b60405180910390f35b61022861072c565b6040516102359190613417565b60405180910390f35b610246610750565b6040516102539190612c0f565b60405180910390f35b61027660048036038101906102719190612bd3565b610776565b6040516102839190612c0f565b60405180910390f35b6102a660048036038101906102a19190613432565b6107a9565b005b6102c260048036038101906102bd919061359c565b610920565b005b6102de60048036038101906102d9919061363c565b610a87565b005b6102fa60048036038101906102f59190612bd3565b610d57565b6040516103079190613712565b60405180910390f35b610318610d6f565b60405161032692919061372d565b60405180910390f35b61034960048036038101906103449190612bd3565b610da0565b604051610357929190613781565b60405180910390f35b61037a600480360381019061037591906137aa565b610dfc565b6040516103879190612c0f565b60405180910390f35b610398610e2f565b6040516103a59190613712565b60405180910390f35b6103c860048036038101906103c391906137d7565b610e35565b005b6103e460048036038101906103df9190612bd3565b6110c0565b005b60606000610431600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206110de565b905080915050919050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104f4906138fd565b60405180910390fd5b61054e86600260008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206110f390919063ffffffff16565b61058d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058490613969565b60405180910390fd5b8460038190555083600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060006105e7878a8a878787600261110a565b9050600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690557f668a2c70c9e33b13c143eac02a389bb5ff706c9939aab9ef9edbbc11216b7b4d878787846040516106499493929190613998565b60405180910390a1505050505050505050565b600061066b8686868686611211565b905095945050505050565b6000806106853388600661124d565b80985081925050506106e7818888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050876106e1906139dd565b87611423565b91505095945050505050565b6040518060400160405280600181526020017f370000000000000000000000000000000000000000000000000000000000000081525081565b7f000000000000000000000000000000000000000000000000000000000000000081565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610837576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161082e906138fd565b60405180910390fd5b61088885600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206110f390919063ffffffff16565b6108c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108be90613969565b60405180910390fd5b60006108d9868989878787600261110a565b90507f6bc93adab97dd835bee818087939b726558bc8d9177650a0018dd05eb00e56c886868360405161090e939291906139f0565b60405180910390a15050505050505050565b6109286115a1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610995576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161098c90613a73565b60405180910390fd5b600084849050905060005b81811015610a7f578383828181106109bb576109ba613a93565b5b90506020020160208101906109d09190612a90565b600660008888858181106109e7576109e6613a93565b5b90506020020160208101906109fc91906137aa565b6005811115610a0e57610a0d613ac2565b5b6005811115610a2057610a1f613ac2565b5b815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508080610a7790613b20565b9150506109a0565b505050505050565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610b15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0c906138fd565b60405180910390fd5b6000610b368787610b25886115ca565b87610b2f906139dd565b6000611211565b9050610b8981600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206110f390919063ffffffff16565b610bc8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bbf90613969565b60405180910390fd5b6000610c2982898989898060000190610be19190613b77565b80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050886006611743565b90508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff1660007fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a898686604051610c8f93929190613c2f565b60405180910390a4836020016020810190610caa9190612a90565b73ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff16856000016020810190610cea9190612a90565b73ffffffffffffffffffffffffffffffffffffffff167f116bfd46451bbd23e7a5f5b7420b28e3d98d4c477f173da513aaaeac3c4baada8760400135886060013589608001358a60a00135604051610d459493929190613c6d565b60405180910390a45050505050505050565b60076020528060005260406000206000915090505481565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b60066020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60035481565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610ec3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eba906138fd565b60405180910390fd5b6000610ee38888610ed3896115ca565b88610edd906139dd565b87611211565b9050610f3681600260008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206110f390919063ffffffff16565b610f75576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6c90613969565b60405180910390fd5b8360038190555082600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600061101e828a8a8a8a8060000190610fd69190613b77565b80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050886006611743565b9050600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690558773ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16867fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a8a86866040516110ad93929190613c2f565b60405180910390a4505050505050505050565b60006110ce823360066117eb565b90506110da81836119a8565b5050565b60606110ec82600001611ac7565b9050919050565b60006111028360000183611b23565b905092915050565b6000611170868689604051602001611123929190613d36565b6040516020818303038152906040526000876040518060400160405280600f81526020017f4175746f6d6174652e657865633a200000000000000000000000000000000000815250611b46565b50809150508215611206576111cb888360008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611be090919063ffffffff16565b507f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b0988886040516111fd929190613d5e565b60405180910390a15b979650505050505050565b6000858585858560405160200161122c959493929190613fdd565b60405160208183030381529060405280519060200120905095945050505050565b6000806000600160058081111561126757611266613ac2565b5b6112719190614037565b905060005b8181101561141357600081600581111561129357611292613ac2565b5b90506112b08160058111156112ab576112aa613ac2565b5b611bf7565b6112ba5750611400565b60008660008360058111156112d2576112d1613ac2565b5b60058111156112e4576112e3613ac2565b5b815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905061131e81611c38565b60006376474e6a60e01b8a8a60405160240161133b92919061408d565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050905060006113dc83836040518060400160405280601881526020017f4175746f6d6174652e7072654372656174655461736b3a200000000000000000815250611caa565b915050808060200190518101906113f391906140e2565b809b50819c505050505050505b808061140b90613b20565b915050611276565b5085859250925050935093915050565b600061143a8686611433876115ca565b8686611211565b905061148d81600260008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206110f390919063ffffffff16565b156114cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114c490614194565b60405180910390fd5b6114dc81878787876006611d34565b61152d81600260008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611f0590919063ffffffff16565b50808573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f73f079427211e7b93db86024054de0b3c4a076a36cf0f86d2c4bf0d112eb7f1d878787604051611590939291906141b4565b60405180910390a495945050505050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60006018826003815181106115e2576115e1613a93565b5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c60108360028151811061164657611645613a93565b5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c6008846001815181106116aa576116a9613a93565b5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c8460008151811061170c5761170b613a93565b5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161717179050919050565b6000806117508584611f1c565b9050611760898989898986612059565b80975081985050506117cc87878a60405160200161177f929190613d36565b6040516020818303038152906040526000876040518060400160405280600f81526020017f4175746f6d6174652e657865633a200000000000000000000000000000000000815250611b46565b50809250506117df8989898989866121cc565b50979650505050505050565b60008060058081111561180157611800613ac2565b5b905060005b81811161199c57600081600581111561182257611821613ac2565b5b905061183f81600581111561183a57611839613ac2565b5b612312565b6118495750611989565b600085600083600581111561186157611860613ac2565b5b600581111561187357611872613ac2565b5b815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506118ad81611c38565b60006314ae992660e01b89896040516024016118ca929190613d5e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050509050600061196b83836040518060400160405280601881526020017f4175746f6d6174652e70726543616e63656c5461736b3a200000000000000000815250611caa565b9150508080602001905181019061198291906141f9565b9850505050505b808061199490613b20565b915050611806565b50839150509392505050565b6119f981600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206110f390919063ffffffff16565b611a38576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a2f90614298565b60405180910390fd5b611a8981600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611be090919063ffffffff16565b507f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b098183604051611abb929190613d5e565b60405180910390a15050565b606081600001805480602002602001604051908101604052809291908181526020018280548015611b1757602002820191906000526020600020905b815481526020019060010190808311611b03575b50505050509050919050565b600080836001016000848152602001908152602001600020541415905092915050565b600060608673ffffffffffffffffffffffffffffffffffffffff168587604051611b7091906142b8565b60006040518083038185875af1925050503d8060008114611bad576040519150601f19603f3d011682016040523d82523d6000602084013e611bb2565b606091505b50809250819350505081158015611bc65750835b15611bd657611bd58184612353565b5b9550959350505050565b6000611bef83600001836124ba565b905092915050565b600060026005811115611c0d57611c0c613ac2565b5b826005811115611c2057611c1f613ac2565b5b03611c2e5760019050611c33565b600090505b919050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611ca7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c9e90614341565b60405180910390fd5b50565b600060608473ffffffffffffffffffffffffffffffffffffffff1684604051611cd391906142b8565b600060405180830381855af49150503d8060008114611d0e576040519150601f19603f3d011682016040523d82523d6000602084013e611d13565b606091505b50809250819350505081611d2c57611d2b8184612353565b5b935093915050565b60008260000151519050611d4b83600001516125ce565b60005b81811015611efb57600084600001518281518110611d6f57611d6e613a93565b5b60200260200101519050611d94816005811115611d8f57611d8e613ac2565b5b6128eb565b611d9e5750611ee8565b6000846000836005811115611db657611db5613ac2565b5b6005811115611dc857611dc7613ac2565b5b815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050611e0281611c38565b600063b0ccbdf060e01b8b8b8b8b8b602001518981518110611e2757611e26613a93565b5b6020026020010151604051602401611e43959493929190614361565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050509050611ee282826040518060400160405280601781526020017f4175746f6d6174652e6f6e4372656174655461736b3a20000000000000000000815250611caa565b50505050505b8080611ef390613b20565b915050611d4e565b5050505050505050565b6000611f14836000018361292c565b905092915050565b606060008351905060008167ffffffffffffffff811115611f4057611f3f612c7b565b5b604051908082528060200260200182016040528015611f6e5781602001602082028036833780820191505090505b50905060005b8281101561204d57846000878381518110611f9257611f91613a93565b5b60200260200101516005811115611fac57611fab613ac2565b5b6005811115611fbe57611fbd613ac2565b5b815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1682828151811061200057611fff613a93565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050808061204590613b20565b915050611f74565b50809250505092915050565b6000606060008451905060005b818110156121b9576120a386828151811061208457612083613a93565b5b6020026020010151600581111561209e5761209d613ac2565b5b61299c565b156121a657600063c10304f760e01b8b8b8b8b6040516024016120c994939291906143c2565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050905060006121848784815181106121405761213f613a93565b5b6020026020010151836040518060400160405280601681526020017f4175746f6d6174652e7072654578656343616c6c3a2000000000000000000000815250611caa565b9150508080602001905181019061219b919061447e565b809a50819b50505050505b80806121b190613b20565b915050612066565b5086869250925050965096945050505050565b60008151905060005b81811015612308576122128482815181106121f3576121f2613a93565b5b6020026020010151600581111561220d5761220c613ac2565b5b6129dd565b156122f557600063b2db0b4160e01b8989898960405160240161223894939291906143c2565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506122f18483815181106122ad576122ac613a93565b5b6020026020010151826040518060400160405280601781526020017f4175746f6d6174652e706f73744578656343616c6c3a20000000000000000000815250611caa565b5050505b808061230090613b20565b9150506121d5565b5050505050505050565b60006002600581111561232857612327613ac2565b5b82600581111561233b5761233a613ac2565b5b03612349576001905061234e565b600090505b919050565b6004602083516123639190614509565b0361245e576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036124025760448301925081836040516020016123b7929190614576565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123f991906133d4565b60405180910390fd5b8160405160200161241391906145e6565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161245591906133d4565b60405180910390fd5b8060405160200161246f9190614654565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124b191906133d4565b60405180910390fd5b600080836001016000848152602001908152602001600020549050600081146125c25760006001826124ec9190614676565b90506000600186600001805490506125049190614676565b905081811461257357600086600001828154811061252557612524613a93565b5b906000526020600020015490508087600001848154811061254957612548613a93565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480612587576125866146aa565b5b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506125c8565b60009150505b92915050565b600081519050600060016005808111156125eb576125ea613ac2565b5b6125f59190614037565b905060008167ffffffffffffffff81111561261357612612612c7b565b5b6040519080825280602002602001820160405280156126415781602001602082028036833780820191505090505b50905060005b838110156127655760008111156126ff57846001826126669190614676565b8151811061267757612676613a93565b5b6020026020010151600581111561269157612690613ac2565b5b8582815181106126a4576126a3613a93565b5b602002602001015160058111156126be576126bd613ac2565b5b116126fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126f590614725565b60405180910390fd5b5b60018286838151811061271557612714613a93565b5b6020026020010151600581111561272f5761272e613ac2565b5b815181106127405761273f613a93565b5b602002602001019015159081151581525050808061275d90613b20565b915050612647565b50806001600581111561277b5761277a613ac2565b5b8151811061278c5761278b613a93565b5b6020026020010151156127d4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127cb906147b7565b60405180910390fd5b80600060058111156127e9576127e8613ac2565b5b815181106127fa576127f9613a93565b5b602002602001015180156128385750806004600581111561281e5761281d613ac2565b5b8151811061282f5761282e613a93565b5b60200260200101515b15612878576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161286f90614849565b60405180910390fd5b806002600581111561288d5761288c613ac2565b5b8151811061289e5761289d613a93565b5b60200260200101516128e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128dc906148db565b60405180910390fd5b50505050565b60006002600581111561290157612900613ac2565b5b82600581111561291457612913613ac2565b5b036129225760019050612927565b600090505b919050565b60006129388383611b23565b612991578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050612996565b600090505b92915050565b6000600260058111156129b2576129b1613ac2565b5b8260058111156129c5576129c4613ac2565b5b036129d357600190506129d8565b600090505b919050565b6000600360058111156129f3576129f2613ac2565b5b826005811115612a0657612a05613ac2565b5b03612a145760019050612a19565b600090505b919050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612a5d82612a32565b9050919050565b612a6d81612a52565b8114612a7857600080fd5b50565b600081359050612a8a81612a64565b92915050565b600060208284031215612aa657612aa5612a28565b5b6000612ab484828501612a7b565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b612afc81612ae9565b82525050565b6000612b0e8383612af3565b60208301905092915050565b6000602082019050919050565b6000612b3282612abd565b612b3c8185612ac8565b9350612b4783612ad9565b8060005b83811015612b78578151612b5f8882612b02565b9750612b6a83612b1a565b925050600181019050612b4b565b5085935050505092915050565b60006020820190508181036000830152612b9f8184612b27565b905092915050565b612bb081612ae9565b8114612bbb57600080fd5b50565b600081359050612bcd81612ba7565b92915050565b600060208284031215612be957612be8612a28565b5b6000612bf784828501612bbe565b91505092915050565b612c0981612a52565b82525050565b6000602082019050612c246000830184612c00565b92915050565b6000819050919050565b612c3d81612c2a565b8114612c4857600080fd5b50565b600081359050612c5a81612c34565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612cb382612c6a565b810181811067ffffffffffffffff82111715612cd257612cd1612c7b565b5b80604052505050565b6000612ce5612a1e565b9050612cf18282612caa565b919050565b600067ffffffffffffffff821115612d1157612d10612c7b565b5b612d1a82612c6a565b9050602081019050919050565b82818337600083830152505050565b6000612d49612d4484612cf6565b612cdb565b905082815260208101848484011115612d6557612d64612c65565b5b612d70848285612d27565b509392505050565b600082601f830112612d8d57612d8c612c60565b5b8135612d9d848260208601612d36565b91505092915050565b60008115159050919050565b612dbb81612da6565b8114612dc657600080fd5b50565b600081359050612dd881612db2565b92915050565b600080600080600080600080610100898b031215612dff57612dfe612a28565b5b6000612e0d8b828c01612a7b565b9850506020612e1e8b828c01612a7b565b9750506040612e2f8b828c01612bbe565b9650506060612e408b828c01612c4b565b9550506080612e518b828c01612a7b565b94505060a089013567ffffffffffffffff811115612e7257612e71612a2d565b5b612e7e8b828c01612d78565b93505060c0612e8f8b828c01612dc9565b92505060e0612ea08b828c01612dc9565b9150509295985092959890939650565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612ee581612eb0565b8114612ef057600080fd5b50565b600081359050612f0281612edc565b92915050565b600080fd5b600080fd5b600067ffffffffffffffff821115612f2d57612f2c612c7b565b5b602082029050602081019050919050565b600080fd5b60068110612f5057600080fd5b50565b600081359050612f6281612f43565b92915050565b6000612f7b612f7684612f12565b612cdb565b90508083825260208201905060208402830185811115612f9e57612f9d612f3e565b5b835b81811015612fc75780612fb38882612f53565b845260208401935050602081019050612fa0565b5050509392505050565b600082601f830112612fe657612fe5612c60565b5b8135612ff6848260208601612f68565b91505092915050565b600067ffffffffffffffff82111561301a57613019612c7b565b5b602082029050602081019050919050565b600061303e61303984612fff565b612cdb565b9050808382526020820190506020840283018581111561306157613060612f3e565b5b835b818110156130a857803567ffffffffffffffff81111561308657613085612c60565b5b8086016130938982612d78565b85526020850194505050602081019050613063565b5050509392505050565b600082601f8301126130c7576130c6612c60565b5b81356130d784826020860161302b565b91505092915050565b6000604082840312156130f6576130f5612f08565b5b6131006040612cdb565b9050600082013567ffffffffffffffff8111156131205761311f612f0d565b5b61312c84828501612fd1565b600083015250602082013567ffffffffffffffff8111156131505761314f612f0d565b5b61315c848285016130b2565b60208301525092915050565b600080600080600060a0868803121561318457613183612a28565b5b600061319288828901612a7b565b95505060206131a388828901612a7b565b94505060406131b488828901612ef3565b935050606086013567ffffffffffffffff8111156131d5576131d4612a2d565b5b6131e1888289016130e0565b92505060806131f288828901612a7b565b9150509295509295909350565b61320881612ae9565b82525050565b600060208201905061322360008301846131ff565b92915050565b600080fd5b60008083601f84011261324457613243612c60565b5b8235905067ffffffffffffffff81111561326157613260613229565b5b60208301915083600182028301111561327d5761327c612f3e565b5b9250929050565b600080fd5b60006040828403121561329f5761329e613284565b5b81905092915050565b6000806000806000608086880312156132c4576132c3612a28565b5b60006132d288828901612a7b565b955050602086013567ffffffffffffffff8111156132f3576132f2612a2d565b5b6132ff8882890161322e565b9450945050604086013567ffffffffffffffff81111561332257613321612a2d565b5b61332e88828901613289565b925050606061333f88828901612a7b565b9150509295509295909350565b600081519050919050565b600082825260208201905092915050565b60005b8381101561338657808201518184015260208101905061336b565b83811115613395576000848401525b50505050565b60006133a68261334c565b6133b08185613357565b93506133c0818560208601613368565b6133c981612c6a565b840191505092915050565b600060208201905081810360008301526133ee818461339b565b905092915050565b600061340182612a32565b9050919050565b613411816133f6565b82525050565b600060208201905061342c6000830184613408565b92915050565b600080600080600080600060e0888a03121561345157613450612a28565b5b600061345f8a828b01612a7b565b97505060206134708a828b01612a7b565b96505060406134818a828b01612bbe565b95505060606134928a828b01612bbe565b945050608088013567ffffffffffffffff8111156134b3576134b2612a2d565b5b6134bf8a828b01612d78565b93505060a06134d08a828b01612dc9565b92505060c06134e18a828b01612dc9565b91505092959891949750929550565b60008083601f84011261350657613505612c60565b5b8235905067ffffffffffffffff81111561352357613522613229565b5b60208301915083602082028301111561353f5761353e612f3e565b5b9250929050565b60008083601f84011261355c5761355b612c60565b5b8235905067ffffffffffffffff81111561357957613578613229565b5b60208301915083602082028301111561359557613594612f3e565b5b9250929050565b600080600080604085870312156135b6576135b5612a28565b5b600085013567ffffffffffffffff8111156135d4576135d3612a2d565b5b6135e0878288016134f0565b9450945050602085013567ffffffffffffffff81111561360357613602612a2d565b5b61360f87828801613546565b925092505092959194509250565b600060c0828403121561363357613632613284565b5b81905092915050565b600080600080600080610160878903121561365a57613659612a28565b5b600061366889828a01612a7b565b965050602061367989828a01612a7b565b955050604087013567ffffffffffffffff81111561369a57613699612a2d565b5b6136a689828a01612d78565b945050606087013567ffffffffffffffff8111156136c7576136c6612a2d565b5b6136d389828a01613289565b93505060806136e489828a0161361d565b9250506101406136f689828a01612dc9565b9150509295509295509295565b61370c81612c2a565b82525050565b60006020820190506137276000830184613703565b92915050565b60006040820190506137426000830185613703565b61374f6020830184612c00565b9392505050565b60006fffffffffffffffffffffffffffffffff82169050919050565b61377b81613756565b82525050565b60006040820190506137966000830185613772565b6137a36020830184613772565b9392505050565b6000602082840312156137c0576137bf612a28565b5b60006137ce84828501612f53565b91505092915050565b600080600080600080600060e0888a0312156137f6576137f5612a28565b5b60006138048a828b01612a7b565b97505060206138158a828b01612a7b565b965050604088013567ffffffffffffffff81111561383657613835612a2d565b5b6138428a828b01612d78565b955050606088013567ffffffffffffffff81111561386357613862612a2d565b5b61386f8a828b01613289565b94505060806138808a828b01612c4b565b93505060a06138918a828b01612a7b565b92505060c06138a28a828b01612dc9565b91505092959891949750929550565b7f47656c61746f666965643a204f6e6c792067656c61746f000000000000000000600082015250565b60006138e7601783613357565b91506138f2826138b1565b602082019050919050565b60006020820190508181036000830152613916816138da565b9050919050565b7f4175746f6d6174652e657865633a205461736b206e6f7420666f756e64000000600082015250565b6000613953601d83613357565b915061395e8261391d565b602082019050919050565b6000602082019050818103600083015261398281613946565b9050919050565b61399281612da6565b82525050565b60006080820190506139ad60008301876131ff565b6139ba6020830186613703565b6139c76040830185612c00565b6139d46060830184613989565b95945050505050565b60006139e936836130e0565b9050919050565b6000606082019050613a0560008301866131ff565b613a1260208301856131ff565b613a1f6040830184613989565b949350505050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b6000613a5d600e83613357565b9150613a6882613a27565b602082019050919050565b60006020820190508181036000830152613a8c81613a50565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613b2b82612c2a565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613b5d57613b5c613af1565b5b600182019050919050565b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112613b9457613b93613b68565b5b80840192508235915067ffffffffffffffff821115613bb657613bb5613b6d565b5b602083019250602082023603831315613bd257613bd1613b72565b5b509250929050565b600081519050919050565b600082825260208201905092915050565b6000613c0182613bda565b613c0b8185613be5565b9350613c1b818560208601613368565b613c2481612c6a565b840191505092915050565b60006060820190508181036000830152613c498186613bf6565b9050613c5860208301856131ff565b613c656040830184613989565b949350505050565b6000608082019050613c826000830187613703565b613c8f6020830186613703565b613c9c6040830185613703565b613ca960608301846131ff565b95945050505050565b600081905092915050565b6000613cc882613bda565b613cd28185613cb2565b9350613ce2818560208601613368565b80840191505092915050565b60008160601b9050919050565b6000613d0682613cee565b9050919050565b6000613d1882613cfb565b9050919050565b613d30613d2b82612a52565b613d0d565b82525050565b6000613d428285613cbd565b9150613d4e8284613d1f565b6014820191508190509392505050565b6000604082019050613d7360008301856131ff565b613d806020830184612c00565b9392505050565b613d9081612eb0565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60068110613dd357613dd2613ac2565b5b50565b6000819050613de482613dc2565b919050565b6000613df482613dd6565b9050919050565b613e0481613de9565b82525050565b6000613e168383613dfb565b60208301905092915050565b6000602082019050919050565b6000613e3a82613d96565b613e448185613da1565b9350613e4f83613db2565b8060005b83811015613e80578151613e678882613e0a565b9750613e7283613e22565b925050600181019050613e53565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600082825260208201905092915050565b6000613ed582613bda565b613edf8185613eb9565b9350613eef818560208601613368565b613ef881612c6a565b840191505092915050565b6000613f0f8383613eca565b905092915050565b6000602082019050919050565b6000613f2f82613e8d565b613f398185613e98565b935083602082028501613f4b85613ea9565b8060005b85811015613f875784840389528151613f688582613f03565b9450613f7383613f17565b925060208a01995050600181019050613f4f565b50829750879550505050505092915050565b60006040830160008301518482036000860152613fb68282613e2f565b91505060208301518482036020860152613fd08282613f24565b9150508091505092915050565b600060a082019050613ff26000830188612c00565b613fff6020830187612c00565b61400c6040830186613d87565b818103606083015261401e8185613f99565b905061402d6080830184612c00565b9695505050505050565b600061404282612c2a565b915061404d83612c2a565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561408257614081613af1565b5b828201905092915050565b60006040820190506140a26000830185612c00565b6140af6020830184612c00565b9392505050565b6140bf816133f6565b81146140ca57600080fd5b50565b6000815190506140dc816140b6565b92915050565b600080604083850312156140f9576140f8612a28565b5b6000614107858286016140cd565b9250506020614118858286016140cd565b9150509250929050565b7f4175746f6d6174652e6372656174655461736b3a204475706c6963617465207460008201527f61736b0000000000000000000000000000000000000000000000000000000000602082015250565b600061417e602383613357565b915061418982614122565b604082019050919050565b600060208201905081810360008301526141ad81614171565b9050919050565b600060608201905081810360008301526141ce8186613bf6565b905081810360208301526141e28185613f99565b90506141f16040830184612c00565b949350505050565b60006020828403121561420f5761420e612a28565b5b600061421d848285016140cd565b91505092915050565b7f4175746f6d6174652e63616e63656c5461736b3a205461736b206e6f7420666f60008201527f756e640000000000000000000000000000000000000000000000000000000000602082015250565b6000614282602383613357565b915061428d82614226565b604082019050919050565b600060208201905081810360008301526142b181614275565b9050919050565b60006142c48284613cbd565b915081905092915050565b7f4175746f6d6174652e5f6d6f64756c65496e697469616c697365643a204e6f7460008201527f20696e6974000000000000000000000000000000000000000000000000000000602082015250565b600061432b602583613357565b9150614336826142cf565b604082019050919050565b6000602082019050818103600083015261435a8161431e565b9050919050565b600060a08201905061437660008301886131ff565b6143836020830187612c00565b6143906040830186612c00565b81810360608301526143a28185613bf6565b905081810360808301526143b68184613bf6565b90509695505050505050565b60006080820190506143d760008301876131ff565b6143e46020830186612c00565b6143f16040830185612c00565b81810360608301526144038184613bf6565b905095945050505050565b600061442161441c84612cf6565b612cdb565b90508281526020810184848401111561443d5761443c612c65565b5b614448848285613368565b509392505050565b600082601f83011261446557614464612c60565b5b815161447584826020860161440e565b91505092915050565b6000806040838503121561449557614494612a28565b5b60006144a3858286016140cd565b925050602083015167ffffffffffffffff8111156144c4576144c3612a2d565b5b6144d085828601614450565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061451482612c2a565b915061451f83612c2a565b92508261452f5761452e6144da565b5b828206905092915050565b600081905092915050565b60006145508261334c565b61455a818561453a565b935061456a818560208601613368565b80840191505092915050565b60006145828285614545565b915061458e8284614545565b91508190509392505050565b7f4e6f4572726f7253656c6563746f720000000000000000000000000000000000600082015250565b60006145d0600f8361453a565b91506145db8261459a565b600f82019050919050565b60006145f28284614545565b91506145fd826145c3565b915081905092915050565b7f556e657870656374656452657475726e64617461000000000000000000000000600082015250565b600061463e60148361453a565b915061464982614608565b601482019050919050565b60006146608284614545565b915061466b82614631565b915081905092915050565b600061468182612c2a565b915061468c83612c2a565b92508282101561469f5761469e613af1565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4175746f6d6174652e5f76616c69644d6f64756c65733a20417363206f6e6c79600082015250565b600061470f602083613357565b915061471a826146d9565b602082019050919050565b6000602082019050818103600083015261473e81614702565b9050919050565b7f4175746f6d6174652e5f76616c69644d6f64756c65733a2054494d452069732060008201527f6465707265636174656400000000000000000000000000000000000000000000602082015250565b60006147a1602a83613357565b91506147ac82614745565b604082019050919050565b600060208201905081810360008301526147d081614794565b9050919050565b7f4175746f6d6174652e5f76616c69644d6f64756c65733a204f6e6c792052455360008201527f4f4c564552206f7220574542335f46554e4354494f4e00000000000000000000602082015250565b6000614833603683613357565b915061483e826147d7565b604082019050919050565b6000602082019050818103600083015261486281614826565b9050919050565b7f4175746f6d6174652e5f76616c69644d6f64756c65733a2050524f585920697360008201527f2072657175697265640000000000000000000000000000000000000000000000602082015250565b60006148c5602983613357565b91506148d082614869565b604082019050919050565b600060208201905081810360008301526148f4816148b8565b905091905056fea26469706673582212201ea424cb154f91a78d903ce21fbd9aaea3001808fcb97341b656af505713ed9864736f6c634300080e00330000000000000000000000007598e84b2e114ab62cab288ce5f7d5f6bad35bba
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101215760003560e01c806380381407116100ad578063b81cd86611610071578063b81cd8661461032f578063cd3d4fb914610360578063ddca3f4314610390578063e1d173a9146103ae578063ee8ca3b5146103ca57610121565b8063803814071461028c578063813785e6146102a8578063abf26d55146102c4578063ac21631a146102e0578063b810c6361461031057610121565b80633323b467116100f45780633323b467146101d257806354fd4d5014610202578063573ea57514610220578063647846a51461023e5780636d2dd29f1461025c57610121565b80630407145c146101265780632e6e0bd01461015657806330a9fe6a146101865780633140576e146101a2575b600080fd5b610140600480360381019061013b9190612a90565b6103e6565b60405161014d9190612b85565b60405180910390f35b610170600480360381019061016b9190612bd3565b61043c565b60405161017d9190612c0f565b60405180910390f35b6101a0600480360381019061019b9190612dde565b61046f565b005b6101bc60048036038101906101b79190613168565b61065c565b6040516101c9919061320e565b60405180910390f35b6101ec60048036038101906101e791906132a8565b610676565b6040516101f9919061320e565b60405180910390f35b61020a6106f3565b60405161021791906133d4565b60405180910390f35b61022861072c565b6040516102359190613417565b60405180910390f35b610246610750565b6040516102539190612c0f565b60405180910390f35b61027660048036038101906102719190612bd3565b610776565b6040516102839190612c0f565b60405180910390f35b6102a660048036038101906102a19190613432565b6107a9565b005b6102c260048036038101906102bd919061359c565b610920565b005b6102de60048036038101906102d9919061363c565b610a87565b005b6102fa60048036038101906102f59190612bd3565b610d57565b6040516103079190613712565b60405180910390f35b610318610d6f565b60405161032692919061372d565b60405180910390f35b61034960048036038101906103449190612bd3565b610da0565b604051610357929190613781565b60405180910390f35b61037a600480360381019061037591906137aa565b610dfc565b6040516103879190612c0f565b60405180910390f35b610398610e2f565b6040516103a59190613712565b60405180910390f35b6103c860048036038101906103c391906137d7565b610e35565b005b6103e460048036038101906103df9190612bd3565b6110c0565b005b60606000610431600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206110de565b905080915050919050565b60006020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b7f0000000000000000000000007598e84b2e114ab62cab288ce5f7d5f6bad35bba73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16146104fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016104f4906138fd565b60405180910390fd5b61054e86600260008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206110f390919063ffffffff16565b61058d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161058490613969565b60405180910390fd5b8460038190555083600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060006105e7878a8a878787600261110a565b9050600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690557f668a2c70c9e33b13c143eac02a389bb5ff706c9939aab9ef9edbbc11216b7b4d878787846040516106499493929190613998565b60405180910390a1505050505050505050565b600061066b8686868686611211565b905095945050505050565b6000806106853388600661124d565b80985081925050506106e7818888888080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f82011690508083019250505050505050876106e1906139dd565b87611423565b91505095945050505050565b6040518060400160405280600181526020017f370000000000000000000000000000000000000000000000000000000000000081525081565b7f0000000000000000000000007598e84b2e114ab62cab288ce5f7d5f6bad35bba81565b600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60016020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b7f0000000000000000000000007598e84b2e114ab62cab288ce5f7d5f6bad35bba73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610837576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161082e906138fd565b60405180910390fd5b61088885600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206110f390919063ffffffff16565b6108c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108be90613969565b60405180910390fd5b60006108d9868989878787600261110a565b90507f6bc93adab97dd835bee818087939b726558bc8d9177650a0018dd05eb00e56c886868360405161090e939291906139f0565b60405180910390a15050505050505050565b6109286115a1565b73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610995576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161098c90613a73565b60405180910390fd5b600084849050905060005b81811015610a7f578383828181106109bb576109ba613a93565b5b90506020020160208101906109d09190612a90565b600660008888858181106109e7576109e6613a93565b5b90506020020160208101906109fc91906137aa565b6005811115610a0e57610a0d613ac2565b5b6005811115610a2057610a1f613ac2565b5b815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508080610a7790613b20565b9150506109a0565b505050505050565b7f0000000000000000000000007598e84b2e114ab62cab288ce5f7d5f6bad35bba73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610b15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0c906138fd565b60405180910390fd5b6000610b368787610b25886115ca565b87610b2f906139dd565b6000611211565b9050610b8981600260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206110f390919063ffffffff16565b610bc8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bbf90613969565b60405180910390fd5b6000610c2982898989898060000190610be19190613b77565b80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050886006611743565b90508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff1660007fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a898686604051610c8f93929190613c2f565b60405180910390a4836020016020810190610caa9190612a90565b73ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff16856000016020810190610cea9190612a90565b73ffffffffffffffffffffffffffffffffffffffff167f116bfd46451bbd23e7a5f5b7420b28e3d98d4c477f173da513aaaeac3c4baada8760400135886060013589608001358a60a00135604051610d459493929190613c6d565b60405180910390a45050505050505050565b60076020528060005260406000206000915090505481565b600080600354600460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16915091509091565b60056020528060005260406000206000915090508060000160009054906101000a90046fffffffffffffffffffffffffffffffff16908060000160109054906101000a90046fffffffffffffffffffffffffffffffff16905082565b60066020528060005260406000206000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60035481565b7f0000000000000000000000007598e84b2e114ab62cab288ce5f7d5f6bad35bba73ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610ec3576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610eba906138fd565b60405180910390fd5b6000610ee38888610ed3896115ca565b88610edd906139dd565b87611211565b9050610f3681600260008b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206110f390919063ffffffff16565b610f75576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6c90613969565b60405180910390fd5b8360038190555082600460006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600061101e828a8a8a8a8060000190610fd69190613b77565b80806020026020016040519081016040528093929190818152602001838360200280828437600081840152601f19601f82011690508083019250505050505050886006611743565b9050600360009055600460006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690558773ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16867fa458375b1282695a972870cbfbc4891a9d856b79d563d17667d171d87e0c527a8a86866040516110ad93929190613c2f565b60405180910390a4505050505050505050565b60006110ce823360066117eb565b90506110da81836119a8565b5050565b60606110ec82600001611ac7565b9050919050565b60006111028360000183611b23565b905092915050565b6000611170868689604051602001611123929190613d36565b6040516020818303038152906040526000876040518060400160405280600f81526020017f4175746f6d6174652e657865633a200000000000000000000000000000000000815250611b46565b50809150508215611206576111cb888360008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611be090919063ffffffff16565b507f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b0988886040516111fd929190613d5e565b60405180910390a15b979650505050505050565b6000858585858560405160200161122c959493929190613fdd565b60405160208183030381529060405280519060200120905095945050505050565b6000806000600160058081111561126757611266613ac2565b5b6112719190614037565b905060005b8181101561141357600081600581111561129357611292613ac2565b5b90506112b08160058111156112ab576112aa613ac2565b5b611bf7565b6112ba5750611400565b60008660008360058111156112d2576112d1613ac2565b5b60058111156112e4576112e3613ac2565b5b815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905061131e81611c38565b60006376474e6a60e01b8a8a60405160240161133b92919061408d565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050905060006113dc83836040518060400160405280601881526020017f4175746f6d6174652e7072654372656174655461736b3a200000000000000000815250611caa565b915050808060200190518101906113f391906140e2565b809b50819c505050505050505b808061140b90613b20565b915050611276565b5085859250925050935093915050565b600061143a8686611433876115ca565b8686611211565b905061148d81600260008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206110f390919063ffffffff16565b156114cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114c490614194565b60405180910390fd5b6114dc81878787876006611d34565b61152d81600260008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611f0590919063ffffffff16565b50808573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167f73f079427211e7b93db86024054de0b3c4a076a36cf0f86d2c4bf0d112eb7f1d878787604051611590939291906141b4565b60405180910390a495945050505050565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d610354905090565b60006018826003815181106115e2576115e1613a93565b5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c60108360028151811061164657611645613a93565b5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c6008846001815181106116aa576116a9613a93565b5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916901c8460008151811061170c5761170b613a93565b5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161717179050919050565b6000806117508584611f1c565b9050611760898989898986612059565b80975081985050506117cc87878a60405160200161177f929190613d36565b6040516020818303038152906040526000876040518060400160405280600f81526020017f4175746f6d6174652e657865633a200000000000000000000000000000000000815250611b46565b50809250506117df8989898989866121cc565b50979650505050505050565b60008060058081111561180157611800613ac2565b5b905060005b81811161199c57600081600581111561182257611821613ac2565b5b905061183f81600581111561183a57611839613ac2565b5b612312565b6118495750611989565b600085600083600581111561186157611860613ac2565b5b600581111561187357611872613ac2565b5b815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506118ad81611c38565b60006314ae992660e01b89896040516024016118ca929190613d5e565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050509050600061196b83836040518060400160405280601881526020017f4175746f6d6174652e70726543616e63656c5461736b3a200000000000000000815250611caa565b9150508080602001905181019061198291906141f9565b9850505050505b808061199490613b20565b915050611806565b50839150509392505050565b6119f981600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206110f390919063ffffffff16565b611a38576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a2f90614298565b60405180910390fd5b611a8981600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020611be090919063ffffffff16565b507f44d83729a43f9c6046446df014d073dd242e0ad672071e9b292f31b669c25b098183604051611abb929190613d5e565b60405180910390a15050565b606081600001805480602002602001604051908101604052809291908181526020018280548015611b1757602002820191906000526020600020905b815481526020019060010190808311611b03575b50505050509050919050565b600080836001016000848152602001908152602001600020541415905092915050565b600060608673ffffffffffffffffffffffffffffffffffffffff168587604051611b7091906142b8565b60006040518083038185875af1925050503d8060008114611bad576040519150601f19603f3d011682016040523d82523d6000602084013e611bb2565b606091505b50809250819350505081158015611bc65750835b15611bd657611bd58184612353565b5b9550959350505050565b6000611bef83600001836124ba565b905092915050565b600060026005811115611c0d57611c0c613ac2565b5b826005811115611c2057611c1f613ac2565b5b03611c2e5760019050611c33565b600090505b919050565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611ca7576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c9e90614341565b60405180910390fd5b50565b600060608473ffffffffffffffffffffffffffffffffffffffff1684604051611cd391906142b8565b600060405180830381855af49150503d8060008114611d0e576040519150601f19603f3d011682016040523d82523d6000602084013e611d13565b606091505b50809250819350505081611d2c57611d2b8184612353565b5b935093915050565b60008260000151519050611d4b83600001516125ce565b60005b81811015611efb57600084600001518281518110611d6f57611d6e613a93565b5b60200260200101519050611d94816005811115611d8f57611d8e613ac2565b5b6128eb565b611d9e5750611ee8565b6000846000836005811115611db657611db5613ac2565b5b6005811115611dc857611dc7613ac2565b5b815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050611e0281611c38565b600063b0ccbdf060e01b8b8b8b8b8b602001518981518110611e2757611e26613a93565b5b6020026020010151604051602401611e43959493929190614361565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050509050611ee282826040518060400160405280601781526020017f4175746f6d6174652e6f6e4372656174655461736b3a20000000000000000000815250611caa565b50505050505b8080611ef390613b20565b915050611d4e565b5050505050505050565b6000611f14836000018361292c565b905092915050565b606060008351905060008167ffffffffffffffff811115611f4057611f3f612c7b565b5b604051908082528060200260200182016040528015611f6e5781602001602082028036833780820191505090505b50905060005b8281101561204d57846000878381518110611f9257611f91613a93565b5b60200260200101516005811115611fac57611fab613ac2565b5b6005811115611fbe57611fbd613ac2565b5b815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1682828151811061200057611fff613a93565b5b602002602001019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff1681525050808061204590613b20565b915050611f74565b50809250505092915050565b6000606060008451905060005b818110156121b9576120a386828151811061208457612083613a93565b5b6020026020010151600581111561209e5761209d613ac2565b5b61299c565b156121a657600063c10304f760e01b8b8b8b8b6040516024016120c994939291906143c2565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050905060006121848784815181106121405761213f613a93565b5b6020026020010151836040518060400160405280601681526020017f4175746f6d6174652e7072654578656343616c6c3a2000000000000000000000815250611caa565b9150508080602001905181019061219b919061447e565b809a50819b50505050505b80806121b190613b20565b915050612066565b5086869250925050965096945050505050565b60008151905060005b81811015612308576122128482815181106121f3576121f2613a93565b5b6020026020010151600581111561220d5761220c613ac2565b5b6129dd565b156122f557600063b2db0b4160e01b8989898960405160240161223894939291906143c2565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505090506122f18483815181106122ad576122ac613a93565b5b6020026020010151826040518060400160405280601781526020017f4175746f6d6174652e706f73744578656343616c6c3a20000000000000000000815250611caa565b5050505b808061230090613b20565b9150506121d5565b5050505050505050565b60006002600581111561232857612327613ac2565b5b82600581111561233b5761233a613ac2565b5b03612349576001905061234e565b600090505b919050565b6004602083516123639190614509565b0361245e576000826020015190506308c379a060e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916036124025760448301925081836040516020016123b7929190614576565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123f991906133d4565b60405180910390fd5b8160405160200161241391906145e6565b6040516020818303038152906040526040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161245591906133d4565b60405180910390fd5b8060405160200161246f9190614654565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016124b191906133d4565b60405180910390fd5b600080836001016000848152602001908152602001600020549050600081146125c25760006001826124ec9190614676565b90506000600186600001805490506125049190614676565b905081811461257357600086600001828154811061252557612524613a93565b5b906000526020600020015490508087600001848154811061254957612548613a93565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b85600001805480612587576125866146aa565b5b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506125c8565b60009150505b92915050565b600081519050600060016005808111156125eb576125ea613ac2565b5b6125f59190614037565b905060008167ffffffffffffffff81111561261357612612612c7b565b5b6040519080825280602002602001820160405280156126415781602001602082028036833780820191505090505b50905060005b838110156127655760008111156126ff57846001826126669190614676565b8151811061267757612676613a93565b5b6020026020010151600581111561269157612690613ac2565b5b8582815181106126a4576126a3613a93565b5b602002602001015160058111156126be576126bd613ac2565b5b116126fe576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126f590614725565b60405180910390fd5b5b60018286838151811061271557612714613a93565b5b6020026020010151600581111561272f5761272e613ac2565b5b815181106127405761273f613a93565b5b602002602001019015159081151581525050808061275d90613b20565b915050612647565b50806001600581111561277b5761277a613ac2565b5b8151811061278c5761278b613a93565b5b6020026020010151156127d4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127cb906147b7565b60405180910390fd5b80600060058111156127e9576127e8613ac2565b5b815181106127fa576127f9613a93565b5b602002602001015180156128385750806004600581111561281e5761281d613ac2565b5b8151811061282f5761282e613a93565b5b60200260200101515b15612878576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161286f90614849565b60405180910390fd5b806002600581111561288d5761288c613ac2565b5b8151811061289e5761289d613a93565b5b60200260200101516128e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128dc906148db565b60405180910390fd5b50505050565b60006002600581111561290157612900613ac2565b5b82600581111561291457612913613ac2565b5b036129225760019050612927565b600090505b919050565b60006129388383611b23565b612991578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050612996565b600090505b92915050565b6000600260058111156129b2576129b1613ac2565b5b8260058111156129c5576129c4613ac2565b5b036129d357600190506129d8565b600090505b919050565b6000600360058111156129f3576129f2613ac2565b5b826005811115612a0657612a05613ac2565b5b03612a145760019050612a19565b600090505b919050565b6000604051905090565b600080fd5b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612a5d82612a32565b9050919050565b612a6d81612a52565b8114612a7857600080fd5b50565b600081359050612a8a81612a64565b92915050565b600060208284031215612aa657612aa5612a28565b5b6000612ab484828501612a7b565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6000819050919050565b612afc81612ae9565b82525050565b6000612b0e8383612af3565b60208301905092915050565b6000602082019050919050565b6000612b3282612abd565b612b3c8185612ac8565b9350612b4783612ad9565b8060005b83811015612b78578151612b5f8882612b02565b9750612b6a83612b1a565b925050600181019050612b4b565b5085935050505092915050565b60006020820190508181036000830152612b9f8184612b27565b905092915050565b612bb081612ae9565b8114612bbb57600080fd5b50565b600081359050612bcd81612ba7565b92915050565b600060208284031215612be957612be8612a28565b5b6000612bf784828501612bbe565b91505092915050565b612c0981612a52565b82525050565b6000602082019050612c246000830184612c00565b92915050565b6000819050919050565b612c3d81612c2a565b8114612c4857600080fd5b50565b600081359050612c5a81612c34565b92915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612cb382612c6a565b810181811067ffffffffffffffff82111715612cd257612cd1612c7b565b5b80604052505050565b6000612ce5612a1e565b9050612cf18282612caa565b919050565b600067ffffffffffffffff821115612d1157612d10612c7b565b5b612d1a82612c6a565b9050602081019050919050565b82818337600083830152505050565b6000612d49612d4484612cf6565b612cdb565b905082815260208101848484011115612d6557612d64612c65565b5b612d70848285612d27565b509392505050565b600082601f830112612d8d57612d8c612c60565b5b8135612d9d848260208601612d36565b91505092915050565b60008115159050919050565b612dbb81612da6565b8114612dc657600080fd5b50565b600081359050612dd881612db2565b92915050565b600080600080600080600080610100898b031215612dff57612dfe612a28565b5b6000612e0d8b828c01612a7b565b9850506020612e1e8b828c01612a7b565b9750506040612e2f8b828c01612bbe565b9650506060612e408b828c01612c4b565b9550506080612e518b828c01612a7b565b94505060a089013567ffffffffffffffff811115612e7257612e71612a2d565b5b612e7e8b828c01612d78565b93505060c0612e8f8b828c01612dc9565b92505060e0612ea08b828c01612dc9565b9150509295985092959890939650565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612ee581612eb0565b8114612ef057600080fd5b50565b600081359050612f0281612edc565b92915050565b600080fd5b600080fd5b600067ffffffffffffffff821115612f2d57612f2c612c7b565b5b602082029050602081019050919050565b600080fd5b60068110612f5057600080fd5b50565b600081359050612f6281612f43565b92915050565b6000612f7b612f7684612f12565b612cdb565b90508083825260208201905060208402830185811115612f9e57612f9d612f3e565b5b835b81811015612fc75780612fb38882612f53565b845260208401935050602081019050612fa0565b5050509392505050565b600082601f830112612fe657612fe5612c60565b5b8135612ff6848260208601612f68565b91505092915050565b600067ffffffffffffffff82111561301a57613019612c7b565b5b602082029050602081019050919050565b600061303e61303984612fff565b612cdb565b9050808382526020820190506020840283018581111561306157613060612f3e565b5b835b818110156130a857803567ffffffffffffffff81111561308657613085612c60565b5b8086016130938982612d78565b85526020850194505050602081019050613063565b5050509392505050565b600082601f8301126130c7576130c6612c60565b5b81356130d784826020860161302b565b91505092915050565b6000604082840312156130f6576130f5612f08565b5b6131006040612cdb565b9050600082013567ffffffffffffffff8111156131205761311f612f0d565b5b61312c84828501612fd1565b600083015250602082013567ffffffffffffffff8111156131505761314f612f0d565b5b61315c848285016130b2565b60208301525092915050565b600080600080600060a0868803121561318457613183612a28565b5b600061319288828901612a7b565b95505060206131a388828901612a7b565b94505060406131b488828901612ef3565b935050606086013567ffffffffffffffff8111156131d5576131d4612a2d565b5b6131e1888289016130e0565b92505060806131f288828901612a7b565b9150509295509295909350565b61320881612ae9565b82525050565b600060208201905061322360008301846131ff565b92915050565b600080fd5b60008083601f84011261324457613243612c60565b5b8235905067ffffffffffffffff81111561326157613260613229565b5b60208301915083600182028301111561327d5761327c612f3e565b5b9250929050565b600080fd5b60006040828403121561329f5761329e613284565b5b81905092915050565b6000806000806000608086880312156132c4576132c3612a28565b5b60006132d288828901612a7b565b955050602086013567ffffffffffffffff8111156132f3576132f2612a2d565b5b6132ff8882890161322e565b9450945050604086013567ffffffffffffffff81111561332257613321612a2d565b5b61332e88828901613289565b925050606061333f88828901612a7b565b9150509295509295909350565b600081519050919050565b600082825260208201905092915050565b60005b8381101561338657808201518184015260208101905061336b565b83811115613395576000848401525b50505050565b60006133a68261334c565b6133b08185613357565b93506133c0818560208601613368565b6133c981612c6a565b840191505092915050565b600060208201905081810360008301526133ee818461339b565b905092915050565b600061340182612a32565b9050919050565b613411816133f6565b82525050565b600060208201905061342c6000830184613408565b92915050565b600080600080600080600060e0888a03121561345157613450612a28565b5b600061345f8a828b01612a7b565b97505060206134708a828b01612a7b565b96505060406134818a828b01612bbe565b95505060606134928a828b01612bbe565b945050608088013567ffffffffffffffff8111156134b3576134b2612a2d565b5b6134bf8a828b01612d78565b93505060a06134d08a828b01612dc9565b92505060c06134e18a828b01612dc9565b91505092959891949750929550565b60008083601f84011261350657613505612c60565b5b8235905067ffffffffffffffff81111561352357613522613229565b5b60208301915083602082028301111561353f5761353e612f3e565b5b9250929050565b60008083601f84011261355c5761355b612c60565b5b8235905067ffffffffffffffff81111561357957613578613229565b5b60208301915083602082028301111561359557613594612f3e565b5b9250929050565b600080600080604085870312156135b6576135b5612a28565b5b600085013567ffffffffffffffff8111156135d4576135d3612a2d565b5b6135e0878288016134f0565b9450945050602085013567ffffffffffffffff81111561360357613602612a2d565b5b61360f87828801613546565b925092505092959194509250565b600060c0828403121561363357613632613284565b5b81905092915050565b600080600080600080610160878903121561365a57613659612a28565b5b600061366889828a01612a7b565b965050602061367989828a01612a7b565b955050604087013567ffffffffffffffff81111561369a57613699612a2d565b5b6136a689828a01612d78565b945050606087013567ffffffffffffffff8111156136c7576136c6612a2d565b5b6136d389828a01613289565b93505060806136e489828a0161361d565b9250506101406136f689828a01612dc9565b9150509295509295509295565b61370c81612c2a565b82525050565b60006020820190506137276000830184613703565b92915050565b60006040820190506137426000830185613703565b61374f6020830184612c00565b9392505050565b60006fffffffffffffffffffffffffffffffff82169050919050565b61377b81613756565b82525050565b60006040820190506137966000830185613772565b6137a36020830184613772565b9392505050565b6000602082840312156137c0576137bf612a28565b5b60006137ce84828501612f53565b91505092915050565b600080600080600080600060e0888a0312156137f6576137f5612a28565b5b60006138048a828b01612a7b565b97505060206138158a828b01612a7b565b965050604088013567ffffffffffffffff81111561383657613835612a2d565b5b6138428a828b01612d78565b955050606088013567ffffffffffffffff81111561386357613862612a2d565b5b61386f8a828b01613289565b94505060806138808a828b01612c4b565b93505060a06138918a828b01612a7b565b92505060c06138a28a828b01612dc9565b91505092959891949750929550565b7f47656c61746f666965643a204f6e6c792067656c61746f000000000000000000600082015250565b60006138e7601783613357565b91506138f2826138b1565b602082019050919050565b60006020820190508181036000830152613916816138da565b9050919050565b7f4175746f6d6174652e657865633a205461736b206e6f7420666f756e64000000600082015250565b6000613953601d83613357565b915061395e8261391d565b602082019050919050565b6000602082019050818103600083015261398281613946565b9050919050565b61399281612da6565b82525050565b60006080820190506139ad60008301876131ff565b6139ba6020830186613703565b6139c76040830185612c00565b6139d46060830184613989565b95945050505050565b60006139e936836130e0565b9050919050565b6000606082019050613a0560008301866131ff565b613a1260208301856131ff565b613a1f6040830184613989565b949350505050565b7f4e4f545f415554484f52495a4544000000000000000000000000000000000000600082015250565b6000613a5d600e83613357565b9150613a6882613a27565b602082019050919050565b60006020820190508181036000830152613a8c81613a50565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000613b2b82612c2a565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613b5d57613b5c613af1565b5b600182019050919050565b600080fd5b600080fd5b600080fd5b60008083356001602003843603038112613b9457613b93613b68565b5b80840192508235915067ffffffffffffffff821115613bb657613bb5613b6d565b5b602083019250602082023603831315613bd257613bd1613b72565b5b509250929050565b600081519050919050565b600082825260208201905092915050565b6000613c0182613bda565b613c0b8185613be5565b9350613c1b818560208601613368565b613c2481612c6a565b840191505092915050565b60006060820190508181036000830152613c498186613bf6565b9050613c5860208301856131ff565b613c656040830184613989565b949350505050565b6000608082019050613c826000830187613703565b613c8f6020830186613703565b613c9c6040830185613703565b613ca960608301846131ff565b95945050505050565b600081905092915050565b6000613cc882613bda565b613cd28185613cb2565b9350613ce2818560208601613368565b80840191505092915050565b60008160601b9050919050565b6000613d0682613cee565b9050919050565b6000613d1882613cfb565b9050919050565b613d30613d2b82612a52565b613d0d565b82525050565b6000613d428285613cbd565b9150613d4e8284613d1f565b6014820191508190509392505050565b6000604082019050613d7360008301856131ff565b613d806020830184612c00565b9392505050565b613d9081612eb0565b82525050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b60068110613dd357613dd2613ac2565b5b50565b6000819050613de482613dc2565b919050565b6000613df482613dd6565b9050919050565b613e0481613de9565b82525050565b6000613e168383613dfb565b60208301905092915050565b6000602082019050919050565b6000613e3a82613d96565b613e448185613da1565b9350613e4f83613db2565b8060005b83811015613e80578151613e678882613e0a565b9750613e7283613e22565b925050600181019050613e53565b5085935050505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b600082825260208201905092915050565b6000613ed582613bda565b613edf8185613eb9565b9350613eef818560208601613368565b613ef881612c6a565b840191505092915050565b6000613f0f8383613eca565b905092915050565b6000602082019050919050565b6000613f2f82613e8d565b613f398185613e98565b935083602082028501613f4b85613ea9565b8060005b85811015613f875784840389528151613f688582613f03565b9450613f7383613f17565b925060208a01995050600181019050613f4f565b50829750879550505050505092915050565b60006040830160008301518482036000860152613fb68282613e2f565b91505060208301518482036020860152613fd08282613f24565b9150508091505092915050565b600060a082019050613ff26000830188612c00565b613fff6020830187612c00565b61400c6040830186613d87565b818103606083015261401e8185613f99565b905061402d6080830184612c00565b9695505050505050565b600061404282612c2a565b915061404d83612c2a565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561408257614081613af1565b5b828201905092915050565b60006040820190506140a26000830185612c00565b6140af6020830184612c00565b9392505050565b6140bf816133f6565b81146140ca57600080fd5b50565b6000815190506140dc816140b6565b92915050565b600080604083850312156140f9576140f8612a28565b5b6000614107858286016140cd565b9250506020614118858286016140cd565b9150509250929050565b7f4175746f6d6174652e6372656174655461736b3a204475706c6963617465207460008201527f61736b0000000000000000000000000000000000000000000000000000000000602082015250565b600061417e602383613357565b915061418982614122565b604082019050919050565b600060208201905081810360008301526141ad81614171565b9050919050565b600060608201905081810360008301526141ce8186613bf6565b905081810360208301526141e28185613f99565b90506141f16040830184612c00565b949350505050565b60006020828403121561420f5761420e612a28565b5b600061421d848285016140cd565b91505092915050565b7f4175746f6d6174652e63616e63656c5461736b3a205461736b206e6f7420666f60008201527f756e640000000000000000000000000000000000000000000000000000000000602082015250565b6000614282602383613357565b915061428d82614226565b604082019050919050565b600060208201905081810360008301526142b181614275565b9050919050565b60006142c48284613cbd565b915081905092915050565b7f4175746f6d6174652e5f6d6f64756c65496e697469616c697365643a204e6f7460008201527f20696e6974000000000000000000000000000000000000000000000000000000602082015250565b600061432b602583613357565b9150614336826142cf565b604082019050919050565b6000602082019050818103600083015261435a8161431e565b9050919050565b600060a08201905061437660008301886131ff565b6143836020830187612c00565b6143906040830186612c00565b81810360608301526143a28185613bf6565b905081810360808301526143b68184613bf6565b90509695505050505050565b60006080820190506143d760008301876131ff565b6143e46020830186612c00565b6143f16040830185612c00565b81810360608301526144038184613bf6565b905095945050505050565b600061442161441c84612cf6565b612cdb565b90508281526020810184848401111561443d5761443c612c65565b5b614448848285613368565b509392505050565b600082601f83011261446557614464612c60565b5b815161447584826020860161440e565b91505092915050565b6000806040838503121561449557614494612a28565b5b60006144a3858286016140cd565b925050602083015167ffffffffffffffff8111156144c4576144c3612a2d565b5b6144d085828601614450565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061451482612c2a565b915061451f83612c2a565b92508261452f5761452e6144da565b5b828206905092915050565b600081905092915050565b60006145508261334c565b61455a818561453a565b935061456a818560208601613368565b80840191505092915050565b60006145828285614545565b915061458e8284614545565b91508190509392505050565b7f4e6f4572726f7253656c6563746f720000000000000000000000000000000000600082015250565b60006145d0600f8361453a565b91506145db8261459a565b600f82019050919050565b60006145f28284614545565b91506145fd826145c3565b915081905092915050565b7f556e657870656374656452657475726e64617461000000000000000000000000600082015250565b600061463e60148361453a565b915061464982614608565b601482019050919050565b60006146608284614545565b915061466b82614631565b915081905092915050565b600061468182612c2a565b915061468c83612c2a565b92508282101561469f5761469e613af1565b5b828203905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4175746f6d6174652e5f76616c69644d6f64756c65733a20417363206f6e6c79600082015250565b600061470f602083613357565b915061471a826146d9565b602082019050919050565b6000602082019050818103600083015261473e81614702565b9050919050565b7f4175746f6d6174652e5f76616c69644d6f64756c65733a2054494d452069732060008201527f6465707265636174656400000000000000000000000000000000000000000000602082015250565b60006147a1602a83613357565b91506147ac82614745565b604082019050919050565b600060208201905081810360008301526147d081614794565b9050919050565b7f4175746f6d6174652e5f76616c69644d6f64756c65733a204f6e6c792052455360008201527f4f4c564552206f7220574542335f46554e4354494f4e00000000000000000000602082015250565b6000614833603683613357565b915061483e826147d7565b604082019050919050565b6000602082019050818103600083015261486281614826565b9050919050565b7f4175746f6d6174652e5f76616c69644d6f64756c65733a2050524f585920697360008201527f2072657175697265640000000000000000000000000000000000000000000000602082015250565b60006148c5602983613357565b91506148d082614869565b604082019050919050565b600060208201905081810360008301526148f4816148b8565b905091905056fea26469706673582212201ea424cb154f91a78d903ce21fbd9aaea3001808fcb97341b656af505713ed9864736f6c634300080e0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000007598e84b2e114ab62cab288ce5f7d5f6bad35bba
-----Decoded View---------------
Arg [0] : _gelato (address): 0x7598e84B2E114AB62CAB288CE5f7d5f6bad35BbA
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000007598e84b2e114ab62cab288ce5f7d5f6bad35bba
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.